Negative 0 means that you have a negative value, but the value is too small to be represented with available precision. It's a way of noting the sign of the value even if the magnitude is unavailable. It could be useful if you're testing edge cases, or if you're looking for signs of an infinity (or negative infinity) in your program.
There are lots of edge cases where the sign of zero affects computation. In floating-point, zero values represent not only the exact value zero but the result of an underflowed computation too small to represent as a non-zero floating point value, so retaining the sign is often important to at least keep such computations on the correct side of a branch cut or limit. For example:
I'll admit I'm not familiar with JS, but assuming that it conforms to the IEEE standard for floating point and you can do bitwise logical operations, can't you just AND it with a 1 in the sign bit place and 0s in all other places, then do a logical right shift of it and see if it's 1? (In the IEEE floating point standard, negative numbers have a 1 in the most significant bit.)
Bitwise operations don't really make sense on floating point data, especially not in javascript. Based on a quick one minute test it appears that javascript just uses the integer part of the number if you try bitwise operations (e.g. 2.6 & 6.2 == 2)
I've always wondered why I only see questions about checking for the exceptional floating point values in a Javascript context, not, for example, a C context, where people probably hit these problems more often. Perhaps C programmers are more prepared, but I think it's more insidious:
This is one of those weird points where Javascript seems like a confused mutant combination of a high-level language and a low-level one. It doesn't give you the power to manipulate the bits of a value, but simultaneously exposes you to all the strange, pointy bits of floating point implementation. It would be a lot nicer if it either gave you the power to fully manipulate the bits, or abstracted away the nastiness of the implementation, but no, they chose wrong in both directions.
If you mean that maybe bitwise operators shouldn't have been included at all if javascript was only going to have one numeric type which would be floating point, maybe you're right. However they can be useful as long as your integers or bit flags are smaller than 2^32 (or 2^31 depending on what you're up to), just pretty slow as every operation needs to do a double->int32->double conversion.
on the other hand, -0 and +0 are a pretty straightforward result of the normal floating point representation, are sometimes useful, and IEEE 754 defines +0==-0. Hiding them under a single 0 would have been more of a hack than having to deal with the difference very very occasionally.
I'm saying Javascript should've thought out its exposed number api a bit better. Either give me the bytes, or give me a number object that does infinite precision behind the scenes for me, don't make me do backflips to figure out whether I'm under/overflowing.
What concerns me about the ES5 solution is that with freeze, apparently we got yet another different way to evaluate equality.
if(value) behaves differently from if (value == true), behaves differently from if (value === true), which again behaves differently from that check in freeze.
IMHO, that freeze check should have behaved the same as ===, so the proposed solution should not have worked.
11 comments
[ 4.1 ms ] story [ 35.3 ms ] threadx/+0 = +infinity
x/-0 = -infinity
sqrt(+0) = 0
sqrt(-0) = nan
log(+0) = -infinity
log(-0) = nan
This is one of those weird points where Javascript seems like a confused mutant combination of a high-level language and a low-level one. It doesn't give you the power to manipulate the bits of a value, but simultaneously exposes you to all the strange, pointy bits of floating point implementation. It would be a lot nicer if it either gave you the power to fully manipulate the bits, or abstracted away the nastiness of the implementation, but no, they chose wrong in both directions.
on the other hand, -0 and +0 are a pretty straightforward result of the normal floating point representation, are sometimes useful, and IEEE 754 defines +0==-0. Hiding them under a single 0 would have been more of a hack than having to deal with the difference very very occasionally.
if(value) behaves differently from if (value == true), behaves differently from if (value === true), which again behaves differently from that check in freeze.
IMHO, that freeze check should have behaved the same as ===, so the proposed solution should not have worked.
Oh well.