Home > Software design >  How to simulate 60% probability in Java with Math.random()
How to simulate 60% probability in Java with Math.random()

Time:04-14

I want to do something if there's a 60% chance (only by using Math.random()). For example, a situation where every value in an array has a 60% chance to be set to 1, otherwise 0.

My confusion is whether we should check

if (Math.random() < 0.6) { ... }

or

if (Math.random() <= 0.6) { ... }

My thought is that it should be the first because 0.0 counts as a possible returned value, but I would like to confirm which one I should use and why.

CodePudding user response:

In theory

It depends on the nearest double approximation of the real value in your comparison.

While this is a simplification, consider that computers store floating point numbers by adding terms of the form 2-n. It follows that most real values can't be represented exactly.

The compiler converts your literal 0.6 the nearest double value, which—in this case—is already less than 0.6. To satisfy your condition as closely as possible to 60% of the time, use Math.random() <= 0.6

Contrast this with a operand of 0.4. Here, the nearest double value is actually greater than 0.4. An operator of <= will still be as close as possible to 40%, but strictly speaking it will be more than 40%, which might violate your intent.

Finally, consider an operand that can be represented exactly, like 0.5. This is where zero matters. If you use <=, your probability is tiny bit higher than 50%; you should definitely use < in that case.

In summary, if your operand is adjusted up to a higher value, <= is most accurate. If your operand is adjusted down to a lower value, < probably captures your intent best. If your operand is not adjusted at all, < is the correct choice.

In practice

For values that are used as-is, or adjusted down, you want to use <, and for operands that are adjusted up, the chance of generating that critical value where <= would make a difference is 2-52. This is on the same order of the chance that a bit will flip in memory, and it's a small enough chance that we neglect it in most applications.

If you were able to use something like nextInt(), then, clearly, your expression would use the < operator: current().nextInt(5) < 3. Other readers will drift toward the same intuition when interpreting an expression like Math.random() < val. They forget that val might not have the same value as the literal real number they wrote in their code.

I recommend you stick with < consistently, even with Math.random(). Though theoretically it's not always the "best" operator, it will give the same results in practice, and it will avoid a lot of head-scratching and bugs by those who read and modify your code later.

CodePudding user response:

Use <. If you ever want to set your odds to 0%, then you might change your comparison value to 0. Since Math.random() can return 0, using <= would not result in a 0% chance. As others have noted, the chance of Math.random() generating the exact number you are testing against is extremely low, so for all values other than 0 you will never notice a difference.

  • Related