arc4random_uniform 转换为浮动时产生非常大的值

arc4random_uniform producing very large values when casting to float

空白项目。代码:

int i = 0;
while (i < 8) {
    float amount = 100-arc4random_uniform(200);
    NSLog(@"amount: %f", amount);
    i++;
}

日志:

amount: 21.000000
amount: 90.000000
amount: 79.000000
amount: 4294967296.000000
amount: 39.000000
amount: 4294967296.000000
amount: 81.000000
amount: 4294967296.000000

4294967296.000000明显在100 - ran(200)范围之外(伪代码)

如果我不将 amount 声明为 float 而是使用 int,则不会发生这种情况。

这是怎么回事?

正如@rob 指出的那样,arc4random_uniform return 是一个 32 位无符号整数类型 (uint32_t),即大于或等于零的数字,从不为负数.因此,编译器计算表达式 100-arc4random_uniform(200) 并期望结果也是一个无符号数。

如果你的示例代码中 arc4random_uniform(200) 的结果恰好大于 100,那么 100-arc4random_uniform(200) 将导致负数被分配给不能表示负数的数据类型,所以你最终会得到意想不到的结果。

您可以向编译器表明您想要处理带符号的数字,正如@rob 所建议的那样,将 arc4random_uniform 的结果转换为带符号的数字(在本例中为 float ):

float amount = 100 - (float)arc4random_uniform(200);

...或者通过明确地使您的其他参数成为有符号数来指示表达式应该 return 有符号数:

float amount = 100.0f - arc4random_uniform(200);