GOTO 0
GOTO 0

Reputation: 47652

Why is Math.pow(-0, -7) === -Infinity?

Is there a rationale for Math.pow(-0, x) evaluating to Infinity for all negative x, except for the odd ones when it's -Infinity? I mean:

Math.pow(-0, -6);          // Infinity
Math.pow(-0, -7);          // -Infinity
Math.pow(-0, -7.33);       // Infinity
Math.pow(-0, -Infinity);   // Infinity

Fiddle

I'm aware that a positive odd power of a negative number is negative, but this is clearly not the case here: -7 is not a positive exponent, and while -0 is indeed a number if you open your mind, it's not a negative one.

This behaviour makes mathematically no sense, and I don't see a practical use or technical convenience for it either, so I suspect the specification must rely on historical/compatibility reasons. Any insights?

Upvotes: 12

Views: 1457

Answers (6)

DerStrom8
DerStrom8

Reputation: 1341

From the documentation we are told the following:

If the first argument is negative zero and the second argument is a negative finite odd integer, or the first argument is negative infinity and the second argument is a positive finite odd integer, then the result is negative infinity.

It appears to be fairly standard between different languages, like Javascript and Java. The methods themselves can differ, but usually the way they are calculated are pretty much the same.

The others did a pretty good job of explaining it, but I wanted to post the above link for future reference.

EDIT: Seeing as the above link is for Java and some people do not believe me that it is fairly standard, check out this Javascript Reference. Notice that it is practically identical to what is stated above. This is because the Math.pow() function, whether in Java, Javascript, C++, or another language, works in the exact same way internally. Your computer is designed to process these commands in the same way, and the language/compiler does not change that. That is why they are effectively the same.

Upvotes: 2

andi
andi

Reputation: 6522

I disagree with your statement: "while -0 is indeed a number if you open your mind, it's not a negative one."

It makes sense mathematically if you take -0 to be equivalent to -1/Infinity. It is, really, so it's not that much of a stretch to look at it from that perspective. And that's a negative number, and can be carried through like a negative number for this .pow() operation. When you combine that with the fact that Math.pow(x, -y) equals 1/Math.pow(x, y), then I think it makes perfect sense that Math.pow(-0, -7) === -Infinity.

Upvotes: 0

user3507600
user3507600

Reputation: 1075

Likely this is due to the way numbers are stored in JavaScript. While you're correct in saying this makes no mathematical sense, unfortunately hardware and software can really only do what they've been explicitly told to do.

First lets look at some basic math.

x ^ -y can be expressed as (1/x) ^ y

(-x) ^ y where y is odd yields a negative result

(-x) ^ y where y is even yields a positive result

Next, lets take into account some basic limits:

lim(x) as x->inf = inf

lim(1/x) as x->inf = 0

lim(-x) as x->inf = -inf

lim(1/(-x)) as x->inf = 0

lim(x) as x->0 = 0

lim(1/x) as x->0 = inf

lim(-x) as x->0 = -0

lim(1/(-x)) as x->0 = -inf

The most interesting one here is the last one.

The most important part of information though is that JavaScript stores numbers as a signed number(reference).

Meaning, when this is evaluated (even though it doesn't make sense to us that 0 can be negative) the sign bit is set for your zero.

When the pow is being evaluated, it likely has a shortcut to see that x / 0 = inf. When the function is returning it probably calculates the sign bit (based on the math at the top) then (using the limits above) sets the number to inf.

Long story short: JavaScript stores it's numbers as signed doubles. The language was not written to differentiate between -0 and +0 and multiplicative functions treat the sign from -0 and +0 like any other number.

Hope this helps.

Upvotes: 1

raina77ow
raina77ow

Reputation: 106385

See, Math.pow(x, -n) is really the same as 1/Math.pow(x, n). You're quite correct in noticing that odd power of a negative number is a negative. And when you do 1/negative, it's still negative, obviously.

But I guess the key part of the question is this:

while -0 is indeed a number if you open your mind, it's not a negative one.

Well, in JavaScript it's actually treated as a negative value in many aspects - apart from direct comparison with 0, of course. For example, Math.abs(-0) returns 0, not -0, and modulo operations save the sign:

0 % 42; // 0
-0 % 42; // -0

One trick stands out of the crowd, however: if you divide any positive number by 0, you'll get Infinity:

console.log(1/0);                // Infinity
console.log(Number.MIN_VALUE/0); // still Infinity

... but if you divide the same number by -0, guess what, you'll get -Infinity:

console.log(Number.MIN_VALUE/-0); // -Infinity

This trick is commonly used when you just have to discern between 0 and -0 - as direct comparison (0 === -0) evaluates to true.


Now, why a language has to have an evil twin negative counterpart of a normal zero? As @Barmar said, the consistency is (most probably) the key reason here. For example, there's a well known rule in JS: when you do modulo operation, the sign of result is the sign of the first operand. So both this -5 % 2 and -5 % -2 result it -1, while both 5 % 2 and 5 % -2 result in 1.

It was a bit surprising for me when I discovered that, but the same rule applies when the first operand is actually divisible by the second one:

 5 % 5;   // 0
-5 % 5;   // -0
-5 % -5;  // -0
 5 % -5;  // 0

... so the rule's still intact. Even more important reason, however, is ability to reverse the operation consistently: if a / b => c, then a / c should be equal to b. In JS, it's true even when b is Infinity or -Infinity, as you get different c (0 in the former, -0 in the latter) and will be able to 'restore' the divisor.

Upvotes: 4

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

Is suspect that this Java script implementation uses following logic:

For even powers:

    Math.pow(-0, -6) ==       // a**(-b) == 1.0/a**b
    1.0 / Math.pow(-0, 6) ==  // (-a)**(2*b) == a**(2*b)
    1.0 / Math.pow(0, 6) ==   // 0**b == 0
    1.0 / 0.0 == 
    Infinity

For odd powers:

    Math.pow(-0, -7) ==       // a**(-b) == 1.0/a**b
    1.0 / Math.pow(-0, 7) ==  // (-a)**(2b+1) == -a**(2b+1) 
   -1.0 / Math.pow(0, 7) ==   // 0**b == 0
   -1.0 / 0.0 == 
   -Infinity

Upvotes: 2

Barmar
Barmar

Reputation: 780879

I believe this is for consistency with powers of other negative numbers. When you raise a negative number to an even power, you always get a positive result. But when you raise a negative number to an odd power, you get a negative result. Raising zero to a negative power always results in infinity (because it's equivalent to dividing by zero); in the case of negative zero, the sign alternates just like other negative numbers.

Upvotes: 8

Related Questions