为什么arc4random()%n出现意外结果?

时间:2013-09-20 08:55:05

标签: objective-c arc4random underflow

我有

for (int i = 0; i< 10; i++) {
    CGFloat longerA = ((arc4random() % 80) - 40) / 100.0f;
    NSLog(@"%f",longerA);
}

,结果是

2013-09-20 11:41:30.801 ****[7025:a0b] 0.390000
2013-09-20 11:41:30.801 ****[7025:a0b] 0.080000
2013-09-20 11:41:30.801 ****[7025:a0b] 0.380000
2013-09-20 11:41:30.801 ****[7025:a0b] 42949672.000000
2013-09-20 11:41:30.802 ****[7025:a0b] 0.060000
2013-09-20 11:41:30.802 ****[7025:a0b] 0.080000
2013-09-20 11:41:30.802 ****[7025:a0b] 0.290000
2013-09-20 11:41:30.802 ****[7025:a0b] 42949672.000000
2013-09-20 11:41:30.803 ****[7025:a0b] 0.350000
2013-09-20 11:41:30.803 ****[7025:a0b] 0.180000

我只是无法理解为什么会有结果42949672.000000

请解释我为何会这样做

我和#34;明白&#34; 它必须随机(80) - 40和结果/ 100.0f,所以我只是不明白这(arc4random()%80)是如何超过79.

2 个答案:

答案 0 :(得分:2)

arc4random返回无符号整数,不能低于0.减去40将下溢并回绕到接近最大值的值。

您的功能中也有modulo bias(某些值会比其他值更常见)。使用arc4random_uniform(80)而不是% 80来纠正此问题。因此,正确的解决方案是:

for (int i = 0; i< 10; i++) {
    CGFloat longerA = (((int)arc4random_uniform(80)) - 40) / 100.0f;
    NSLog(@"%f",longerA);
}

答案 1 :(得分:0)

记录arc4random函数返回u_int32_t。这听起来像一个无符号类型,所以当你滚动一个数字&lt; 40然后减去40,你得到一个arithmetic underflow。这就是大数字的来源(2 ^ 32 - 某事)。