问题
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?
回答1:
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;
}
回答2:
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
.
回答3:
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
回答4:
A simpler variant would be:
- (float)randomValueBetween:(float)low andValue:(float)high {
return (arc4random() % * (high - low)) + low;
}
Since you're already doing a mod operation why not do it directly on the range of interest?
Also, why are you passing in floats (and returning floats) if you only ever pass in round numbers? Integers are more efficient.
来源:https://stackoverflow.com/questions/1131101/whats-wrong-with-this-randomize-function