arc4random_uniform在转换为float时产生非常大的值

时间:2017-01-26 23:17:22

标签: objective-c casting floating-point integer arc4random

空白项目。代码:

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,则不会发生这种情况。

这里发生了什么?

1 个答案:

答案 0 :(得分:1)

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

如果示例代码中arc4random_uniform(200)的结果恰好大于100,那么100-arc4random_uniform(200)将导致将负数分配给无法表示负数的数据类型,因此您&# 39;最终会出现意想不到的结果。

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

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

...或者通过明确地将您的另一个参数设置为带符号的数字来指示表达式应该返回带符号的数字:

float amount = 100.0f - arc4random_uniform(200);