Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's wrong with this randomize function?

I give it 0 and 400 and it returns me sometimes values above 400. That doesn't make sense.

- (float)randomValueBetween:(float)low andValue:(float)high {
    return (((float) arc4random() / RAND_MAX) * (high - low)) + low;
}

that's actually a snippet I found on the net. Maybe someone can see the bug in there?

like image 690
Thanks Avatar asked Jul 15 '09 12:07

Thanks


3 Answers

The manual page for arc4random indicates that the returned value can be anywhere in the range valid for u int32 (i.e. 0 to (2**32)-1). This means you'll want to divide by 0xFFFFFFFF, instead of RAND_MAX, which I would imagine is less (it is library dependant however, so you'll have to check exactly what it is).

Your function should thus become:

- (float)randomValueBetween:(float)low andValue:(float)high {
    return (((float) arc4random() / 0xFFFFFFFFu) * (high - low)) + low;
}
like image 104
Noldorin Avatar answered Oct 10 '22 23:10

Noldorin


  • arc4random returns a pseudo-random value from zero to (2 ^ 32 - 1)
  • RAND_MAX has a default value of (2 ^ 31 - 1)

So the function is probably multiplying the (high - low) range by up to a factor of 2, for random values in the range 0 - 800.

like image 31
Daniel F. Thornton Avatar answered Oct 10 '22 22:10

Daniel F. Thornton


On the iPhone, RAND_MAX is 0x7fffffff (2147483647), while arc4random() will return a maximum value of 0x100000000, so (4294967296) / (2147483647) = 2..... 2 * (400-0) + 0 = 800 ! the max value the method can return

like image 3
Matthieu Avatar answered Oct 10 '22 23:10

Matthieu