Teed Ferguson
Teed Ferguson

Reputation: 317

Random int function

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

Answers (4)

GBlodgett
GBlodgett

Reputation: 12819

The first one can return -3, it is just very unlikely.

Math.random():

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

Krease
Krease

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

MyStackRunnethOver
MyStackRunnethOver

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

Ben Patterson
Ben Patterson

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

Related Questions