使用带有%u和%x的unsigned int时出现意外值

时间:2013-07-18 10:27:06

标签: ios c

今天我正在开发一个示例iOS应用程序,其中包含如下代码:

unsigned int uCount = 0;
int iJoke = -7;
uCount = uCount + iJoke;

但是当我打印它时:

╔══════════════════╦══════════════════════╦════════════╗
║ Format Specifier ║   Print Statement    ║   Output   ║
╠══════════════════╬══════════════════════╬════════════╣
║ %d               ║ NSLog(@"%d",uCount); ║ -7         ║
║ %u               ║ NSLog(@"%u",uCount); ║ 4294967289 ║
║ %x               ║ NSLog(@"%x",uCount); ║ fffffff9   ║
╚══════════════════╩══════════════════════╩════════════╝

我预计%u的输出为7。

然后我用了:

unsigned int i = 0;
int j = -7;
i = i + abs(j);

输出就像:

╔══════════════════╦══════════════════════╦════════╗
║ Format Specifier ║   Print Statement    ║ Output ║
╠══════════════════╬══════════════════════╬════════╣
║ %d               ║ NSLog(@"%d",uCount); ║      7 ║
║ %u               ║ NSLog(@"%u",uCount); ║      7 ║
║ %x               ║ NSLog(@"%x",uCount); ║      7 ║
╚══════════════════╩══════════════════════╩════════╝

虽然我的问题已通过abs()解决,但我很想知道为什么%u在我的第一个案例中给出了4294967289

请帮助,提前致谢。

3 个答案:

答案 0 :(得分:6)

此赋值将以表示-7(以2的补码)的模式分配给unsigned int。这将是非常大的无符号值。

对于32位int,这将是2^32 - 7 = 4294967289

标准说它如下所示

"If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2^n where n is the number of bits used to represent the unsigned type). [ Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). —end note ]

答案 1 :(得分:0)

ARM在Two's Complement中存储负数,因此-7在被视为无符号数时表示为0xfffffff9

表示这样的负数的主要优点是添加有符号整数的指令与添加无符号整数的指令相同。

答案 2 :(得分:0)

ijoke被提升为无符号整数。在大多数编译器中,带符号的位被扭曲以给出一个大的正数。

当无符号操作数被转移时,转换规则会更复杂。

例如,假设int是16位而long是32位。然后-1L< 1U,因为1U是一个int,它被提升为有符号长整数。

因为你似乎有一个32位的int:

4294967296 - 7 = 4294967289

通常,大多数隐式转换是将“较窄”操作数转换为“更宽”操作数而不会丢失信息的转换。