Reputation: 317
Can someone explain why (int) (Math.random()*12-3)
returns values between -2 and 8 while (int) (Math.random()*12)-3
returns between -3 and 8?
The difference is the placement of a parenthesis, but I don't know the "under the hood" reason why it makes a difference. If the lowest value that Math.random()
can return is 0, that 0*12 = 0 and both should end up with -3 as a minimum.
I assume it has to do with casting to an int and 0.x to 1. Is it just that it is (theoretically) impossible to hit 0.00000000...?
Upvotes: 5
Views: 128
Reputation: 12819
The first one can return -3
, it is just very unlikely.
Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.
So when you have (int) (Math.random()*12-3)
, inside the inner parentheses, the result will be a double, which you cast to an int
. This truncates the decimal places, so unless Math.random() * 12
returns exactly 0 (And then once you subtract 3 to get exactly -3), Math.random() * 12 -3
, will return at the lowest 2.{...}
, and it will get truncated to -2.
When you do:
(int) (Math.random()*12)-3
The casting is of greater precedence than the subtraction, so it is greater likelihood to get truncated to 0
. Then you subtract three, which results in -3
.
Upvotes: 3
Reputation: 16215
They both can reach -3.
Math.random()
returns a double
between 0 (inclusive) and 1 (exclusive)
Casting to int
truncates the value closer to 0: (int)(-2.9) == -2
, and (int)(2.9) == 2
. Effectively, it makes negative numbers "bigger" and positive numbers "smaller".
The difference is (int) (Math.random()*12)-3
evaluates only the Math.random()*12
part and then casts to int
- any random value less than 1/12 will result in a result of 0 when cast to an int, then subtracting 3 leaves -3.
The original case can result in -3, but ONLY when Math.random()
provides a result of 0 - much more rare than providing a value less than 1/12.
Upvotes: 0
Reputation: 5275
This is due to order of operations along with the fact that (int) someNumber
truncates someNumber
if it is a double
. This means that in the first case, it is exceedingly improbable (but possible) that Math.random()
returns zero, in which case the expression would evaluate to -3. However, any other small value produces (int) -2.[...]
which becomes -2 because it is truncated (the decimals are simply cut off).
In the other case, (int)
is applied to Math.random()*12
, then 3 is subtracted from the result. Here, any time Math.random()*12 < 1
you get 0 - 3 = -3
as the result. This happens about 1/12
of the time, thus you see it producing -3 quite often.
Upvotes: 1
Reputation: 61
Casting to int with (int) truncates the floating point value towards 0. So with (int) (Math.random()*12-3)
, even if we get -2.9999, (int) -2.9999
= -2. Whereas if we calculate (int) (Math.random()*12)
, we can truncate, for example, 0.5 to 0, and then 0-3 = -3.
Upvotes: 0