When dealing with floating-point numbers, −0 is a different number from 0. I am building a timer application in JavaScript and apparently found out the hard way when converting the number of minutes into a string.
For any other number of minutes than −0, it works just fine to do this:
var minutes = (time_balance_s/60);
minutes = Math.sign(minutes) * Math.floor(Math.abs(minutes));
var seconds = time_balance_s - (minutes * 60);
seconds = Math.floor(Math.abs(seconds));
displayString = minutes+":"+seconds.toString().padStart(2, '0');
But for −0, the minus sign is omitted, making the case where we are within a minute past our time indistinguishable from the case where we have less than a minute left. (i.e. if there are 21 seconds left, or if we are 21 seconds overtime, the time shows "0:21")
I initially thought it was something to do with order or operations and "+" being ambiguous in JavaScript. But even this won't work:
var minutes = (time_balance_s/60);
minutes = Math.sign(minutes) * Math.floor(Math.abs(minutes));
var seconds = time_balance_s - (minutes * 60);
seconds = Math.floor(Math.abs(seconds));
displayString = minutes.toString()+":"+seconds.toString().padStart(2, '0');
After a lot of searching, I found I had to make a special case to handle this, and use a special Object.is
operation. This is frustrating.
var minutes = (time_balance_s/60);
minutes = Math.sign(minutes) * Math.floor(Math.abs(minutes));
var seconds = time_balance_s - (minutes * 60);
seconds = Math.floor(Math.abs(seconds));
if (Object.is(minutes, -0)) {
displayString = "-0"+":"+seconds.toString().padStart(2, '0');
} else {
displayString = minutes.toString()+":"+seconds.toString().padStart(2, '0');
}
Mozilla developer docs suggest this is deliberate:
Both
0
and-0
have"0"
as their string representation.Infinity
returns"Infinity"
andNaN
returns"NaN"
.
And I finally (well after a while) did find that someone else was asking about this behaviour and also a link to a standard. The solution of util.inspect
won't work since this is browser JavaScript not Node.js JavaScript. The standard seems to explain how numbers should be handled but doesn't seem to explain why they are handled that way.
I'm wondering why JavaScript is like this. Why doesn't −0 become "-0"
when converting it to a string? Is there a historic reason for this? Was there much discussion about it?
I know it's a standard now and likely wouldn't be changed, but it seems strange to me and I was curious if anyone knew. Is there some advantage case where having −0 become "0"
is beneficial? Why didn't more people fight for −0 to be "-0"
when the standard was being put together?