Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Math.pow(0, 0) === 1?

We all know that 00 is indeterminate.

But, javascript says that:

Math.pow(0, 0) === 1 // true 

and C++ says the same thing:

pow(0, 0) == 1 // true 

WHY?

I know that:

>Math.pow(0.001, 0.001) 0.9931160484209338 

But why does Math.pow(0, 0) throw no errors? Or maybe a NaN would be better than 1.

like image 817
Ionică Bizău Avatar asked Nov 13 '13 14:11

Ionică Bizău


People also ask

Why does math POW return a double?

pow Example. The method raises a to the power of b and returns the result as double. In other words, a is multiplied by itself b times.

Why is math POW so slow?

Math. pow is slow because it deals with an equation in the generic sense, using fractional powers to raise it to the given power. It's the lookup it has to go through when computing that takes more time. Simply multiplying numbers together is often faster, since native calls in Java are much more efficient.

Why is math POW a static method?

It's a static method on Math class, which means you don't have to instantiate a Math instance to call it. The power of a number is the number of times the number is multiplied by itself.

What does math pow () do?

The Math. pow() function returns the base to the exponent power, as in base exponent , the base and the exponent are in decimal numeral system.


2 Answers

In C++ The result of pow(0, 0) the result is basically implementation defined behavior since mathematically we have a contradictory situation where N^0 should always be 1 but 0^N should always be 0 for N > 0, so you should have no expectations mathematically as to the result of this either. This Wolfram Alpha forum posts goes into a bit more details.

Although having pow(0,0) result in 1 is useful for many applications as the Rationale for International Standard—Programming Languages—C states in the section covering IEC 60559 floating-point arithmetic support:

Generally, C99 eschews a NaN result where a numerical value is useful. [...] The results of pow(∞,0) and pow(0,0) are both 1, because there are applications that can exploit this definition. For example, if x(p) and y(p) are any analytic functions that become zero at p = a, then pow(x,y), which equals exp(y*log(x)), approaches 1 as p approaches a.

Update C++

As leemes correctly pointed out I originally linked to the reference for the complex version of pow while the non-complex version claims it is domain error the draft C++ standard falls back to the draft C standard and both C99 and C11 in section 7.12.7.4 The pow functions paragraph 2 says (emphasis mine):

[...]A domain error may occur if x is zero and y is zero.[...]

which as far as I can tell means this behavior is unspecified behavior Winding back a bit section 7.12.1 Treatment of error conditions says:

[...]a domain error occurs if an input argument is outside the domain over which the mathematical function is defined.[...] On a domain error, the function returns an implementation-defined value; if the integer expression math_errhandling & MATH_ERRNO is nonzero, the integer expression errno acquires the value EDOM; [...]

So if there was a domain error then this would be implementation defined behavior but in both the latest versions of gcc and clang the value of errno is 0 so it is not a domain error for those compilers.

Update Javascript

For Javascript the ECMAScript® Language Specification in section 15.8 The Math Object under 15.8.2.13 pow (x, y) says amongst other conditions that:

If y is +0, the result is 1, even if x is NaN.

like image 56
Shafik Yaghmour Avatar answered Sep 22 '22 03:09

Shafik Yaghmour


In JavaScript Math.pow is defined as follows:

  • If y is NaN, the result is NaN.
  • If y is +0, the result is 1, even if x is NaN.
  • If y is −0, the result is 1, even if x is NaN.
  • If x is NaN and y is nonzero, the result is NaN.
  • If abs(x)>1 and y is +∞, the result is +∞.
  • If abs(x)>1 and y is −∞, the result is +0.
  • If abs(x)==1 and y is +∞, the result is NaN.
  • If abs(x)==1 and y is −∞, the result is NaN.
  • If abs(x)<1 and y is +∞, the result is +0.
  • If abs(x)<1 and y is −∞, the result is +∞.
  • If x is +∞ and y>0, the result is +∞.
  • If x is +∞ and y<0, the result is +0.
  • If x is −∞ and y>0 and y is an odd integer, the result is −∞.
  • If x is −∞ and y>0 and y is not an odd integer, the result is +∞.
  • If x is −∞ and y<0 and y is an odd integer, the result is −0.
  • If x is −∞ and y<0 and y is not an odd integer, the result is +0.
  • If x is +0 and y>0, the result is +0.
  • If x is +0 and y<0, the result is +∞.
  • If x is −0 and y>0 and y is an odd integer, the result is −0.
  • If x is −0 and y>0 and y is not an odd integer, the result is +0.
  • If x is −0 and y<0 and y is an odd integer, the result is −∞.
  • If x is −0 and y<0 and y is not an odd integer, the result is +∞.
  • If x<0 and x is finite and y is finite and y is not an integer, the result is NaN.

emphasis mine

as a general rule, native functions to any language should work as described in the language specification. Sometimes this includes explicitly "undefined behavior" where it's up to the implementer to determine what the result should be, however this is not a case of undefined behavior.

like image 37
zzzzBov Avatar answered Sep 23 '22 03:09

zzzzBov