سؤال

Given the following code NSInteger random = arc4random_uniform(3) - 1;

this code compiled for armv7, armv7 and i386 (tested on an iPhone 5 and iOS Simulator) produce an uniform distribution of the element {-1,0,1}; but when compiled for arm64 and run on iPhone 5s it produce {4294967295, 0, 1}?

هل كانت مفيدة؟

المحلول

arc4random_uniform returns an an unsigned int, - 1 on it will return you to the largest 32 bit integer size 4294967295.

You'll need to cast arc4random_uniform(3) into an int before you can -1 on it.

Example of the 64-bit 32-bit unsigned/signed integer problem

Rule 4: The sum of a signed value and an unsigned value of the same size is an unsigned value.

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); Problem: When this code is executed in the 32-bit runtime, the result is -1 (0xffffffff). When the code is run in the 64-bit runtime, the result is 4294967295 (0x00000000ffffffff), which is probably not what you were expecting.

Cause: Why does this happen? First, the two numbers are added. A signed value plus an unsigned value results in an unsigned value (rule 4). Next, that value is promoted to a larger type. This promotion does not cause sign extension.

Solution: To fix this problem in a 32-bit-compatible way, cast b to a long integer. This cast forces the non-sign-extended promotion of b to a 64-bit type prior to the addition, thus forcing the signed integer to be promoted (in a signed fashion) to match. With that change, the result is the expected -1.

stolen from the apple 64-Bit Transition Guide.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top