1

给定以下代码 NSInteger random = arc4random_uniform(3) - 1;

此代码为 armv7、armv7 和 i386 编译(在 iPhone 5 和 iOS 模拟器上测试)产生元素 {-1,0,1} 的均匀分布;但是当为 arm64 编译并在 iPhone 5s 上运行时,它会产生 {4294967295, 0, 1}?

4

1 回答 1

3

arc4random_uniform 返回一个无符号整数, - 1 将返回最大的 32 位整数大小 4294967295。

您需要先将 arc4random_uniform(3) 转换为 int ,然后才能对其进行 -1 。

64 位 32 位无符号/有符号整数问题示例

规则 4:有符号值和相同大小的无符号值之和为无符号值。

int a=-2;
unsigned int b=1;
long c = a + b;
long long d=c; // to get a consistent size for printing.

printf("%lld\n", d); 问题:在 32 位运行时执行此代码时,结果为 -1 (0xffffffff)。当代码在 64 位运行时运行时,结果为 4294967295 (0x00000000ffffffff),这可能不是您所期望的。

原因:为什么会发生这种情况?首先,将两个数字相加。有符号值加上无符号值会产生无符号值(规则 4)。接下来,将该值提升为更大的类型。此促销不会导致标志延长。

解决方案:要以兼容 32 位的方式解决此问题,请将 b 转换为长整数。此强制转换在加法之前强制将 b 的非符号扩展提升为 64 位类型,从而强制提升有符号整数(以有符号方式)以匹配。通过这种更改,结果是预期的 -1。

从苹果 64 位过渡指南中窃取。

于 2013-10-21T22:18:18.067 回答