What's wrong with this randomize function?

心已入冬 提交于 2019-12-21 17:07:23

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!