Reputation: 53236
I just wanted to generate random integer number in range <-1,1>
, that is -1, 0 or 1. I think this code nails it:
Math.round(Math.random()*2-1)
But I'm getting one more value apart from -1, 0 and 1. I'm not sure what is that supposed to be:
Now I don't think this is implementation error, but if it is, I'm using Firefox 41 and same thing happened in Google Chrome 39. When I tried to log -0
in console it appeared as -0
but -0
converted to String
appears as "0"
. What is it? Can I use it for something, like some cool programming hacks and workarounds? Can it cause some errors if I don't just ignore it?
Upvotes: 4
Views: 1118
Reputation: 34137
Two Zeros
Because JavaScript’s numbers keep magnitude and sign separate, each nonnegative number has a negative, including 0. The rationale for this is that whenever you represent a number digitally, it can become so small that it is indistinguishable from 0, because the encoding is not precise enough to represent the difference. Then a signed zero allows you to record “from which direction” you approached zero; that is, what sign the number had before it was considered zero.
from here
More technical stuff if you are interested.
The implementation of -0 and +0 is introduced in 1985 by IEEE as part of the IEEE 754 standard. The standard addressed many problems found in the diverse floating point implementations that made them difficult to use reliably and portably.
The standard defines
Upvotes: 5
Reputation: 288480
ECMAScript has two zero numbers: +0
and -0
.
They are considered equal by most comparison algorithms:
+0 == -0 // true (Equality comparison)
+0 === -0 // true (StrictEquality comparison)
[+0].includes(-0) // true (SameValueZero comparison)
However, they are different number values:
Object.is(+0, -0) // false (SameValue comparison)
Usually, both zeros behave identically in mathematical calculations. However,
1 / +0 === +Infinity
1 / -0 === -Infinity
In this case, you get -0
because Math.round
is defined as follows:
If x is less than 0 but greater than or equal to -0.5, the result is −0.
In general, if you have an integer between −231 and 231−1, and you want to convert it to +0
if it's -0
, and don't alter it otherwise, you can use bitwise OR:
-1 | 0 // -1
-0 | 0 // +0
+0 | 0 // +0
+1 | 0 // +1
However, in your case you could just take the -1
outside of Math.round
:
Math.round(Math.random()*2) - 1
But note using Math.round
will produce a non-uniform probability distribution. Consider using
Math.floor(Math.random()*3) - 1
Upvotes: 3
Reputation: 5525
The function Math.round
works as specified in the standard:
If x is less than 0 but greater than or equal to -0.5, the result is −0.
Math.random
returns number between 0 (zero) and 1 (one) exclusively, so you will have several occurances of that rule.
Upvotes: 2