4

I'm working on creating a range of numbers between 1 and 2 using the imported math.random() class.

Here's how I got it working so far, however I can't see how it would work:

int tmp = (int)(Math.random()*1)+1;

Anyonould?e know if that actually works to get the range? if not.. then what

EDIT: Looking for either the number 1 or 2.

zeck
  • 41
  • 1
  • 1
  • 3

4 Answers4

10

If you want the values 1 or 2 with equal probability, then int temp = (Math.random() <= 0.5) ? 1 : 2; is all you need. That gives you a 1 or a 2, each with probability 1/2.

pjs
  • 18,696
  • 4
  • 27
  • 56
  • Not really, you should do < 0.5 and not <= 0.5 for equal probability, right? – peter.petrov Jan 21 '14 at 00:18
  • 1
    @peter.petrov Mathematically it's discrete inversion of the CDF, and CDF's are `<=` inequalities. Computationally you could argue that the RNG yields 0 but not 1, so there's an asymmetry to the tune of one part in 2**31-1, which practically speaking makes no difference. Since I'm a statistician by trade, I tend to go with a straight-up translation the mathematical definition. – pjs Jan 21 '14 at 00:21
  • @peter.petrov This also would lend itself easily to splitting the mix to a different proportion. Simply change the proportion value in the test to a new target. – pjs Jan 21 '14 at 00:28
  • @peter.petrov I think you could argue that mathematically you have two equivalent ranges, while technically I don't. Yours requires more computation by a hair (addition, floor, and casting vs a single comparison). I don't think any statistical test could tell the difference in the results based on any sample size people are actually likely to draw. – pjs Jan 21 '14 at 00:38
  • @pjs I think the asymmetry is more like one part in 2**52-1, not 2**31-1. `Math.random` returns a `double` which has 52 significant bits of precision. – ajb Jan 21 '14 at 00:58
  • @ajb Thanks for the info. I think the bottom line is that nobody would be able to tell the difference whether you use a `<` or a `<=` on this one. – pjs Jan 21 '14 at 01:12
6
int tmp = (int) ( Math.random() * 2 + 1); // will return either 1 or 2

Math.random() returns numbers from [0, 1). Because (int) always rounds down (floors), you actually want the range [1,3), so that [1,2) will be rounded to 1 and [2,3) will be rounded to 2.

Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
poitroae
  • 21,129
  • 10
  • 63
  • 81
2

Try this.

int tmp = (int)( Math.floor( Math.random() + 1.5 ) )

Math.random() -> [0, 1)

Math.random() + 1.5 -> [1.5, 2.5)

So when you take the floor, it is either 1 or 2 with equal
probability because [1.5, 2.5) = [1.5, 2) U [2, 2.5)
and length([1.5, 2)) = length([2, 2.5)) = 0.5.

peter.petrov
  • 38,363
  • 16
  • 94
  • 159
1

Ok, you want to use Math.random, but you could use java.util.Random so no casting or rounding is required:

    java.util.Random random = new java.util.Random();
    int tmp = random.nextInt(2) + 1;
Raul Guiu
  • 2,374
  • 22
  • 37
  • 2
    +1 I was looking at these answers and was wondering why no one was using `Random`. Especially since you can replace it with `SecureRandom`. – Adam Gent Jan 21 '14 at 00:24
  • 1
    I'm using this code for a class, we're supposed to say in the curriculum and math.random() was the only random taught. – zeck Jan 21 '14 at 00:25
  • It is part of `java.util`, that class is there to solve this kind of problems. – Raul Guiu Jan 21 '14 at 00:30