我很想知道如果我给无符号变量分配负值会发生什么。
代码看起来有点像这样。
unsigned int nVal = 0;
nVal = -5;
它没有给我任何编译器错误。当我运行程序时,nVal
被分配了一个奇怪的值!是否可以将某个2的补码值分配给nVal
?
答案 0 :(得分:59)
官方回答 - 第4.7节conv.integral
“如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2 n ,其中
n
是用于表示的整数无符号类型)。[注意:在二进制补码表示中,这种转换是概念性的,并且位模式没有变化(如果没有截断)。-end note]
这实质上意味着如果底层架构存储的方法不是Two的补码(如Signed Magnitude,或One的补语),那么转换为unsigned必须表现得好像是Two's Complement。
答案 1 :(得分:28)
它将表示-5(2的补码)的位模式分配给unsigned int。这将是一个很大的无符号值。对于32位整数,这将是2 ^ 32 - 5或4294967291
答案 2 :(得分:4)
它将显示为最大无符号整数值的正整数 - 4(值取决于计算机体系结构和编译器)。
顺便说一句
您可以通过编写一个简单的C ++“hello world”类型程序来检查这一点并亲自看看
答案 3 :(得分:4)
你是对的,有符号整数以2的补码形式存储,无符号整数存储在unsigned binary representation中。 C(和C ++)不区分这两者,所以你最终得到的值只是2的补码二进制表示的无符号二进制值。
答案 4 :(得分:0)
是的,你是对的。分配的实际值类似于除第三个以外的所有位设置。 -1是所有位设置(十六进制:0xFFFFFFFF),-2是除第一个以外的所有位,依此类推。你会看到的可能是十六进制值0xFFFFFFFB,十进制对应于4294967291。
答案 5 :(得分:0)
当您为无符号变量分配负值时,它使用2的补数方法来处理它,在此方法中,它将所有0翻转为1,将所有1翻转为0,然后对其加1。在您的情况下,您要处理的是4字节(32位)的int,因此它尝试对32位数字使用2的补码方法,这会导致高位翻转。例如:
┌─[student@pc]─[~]
└──╼ $pcalc 0y00000000000000000000000000000101 # 5 in binary
5 0x5 0y101
┌─[student@pc]─[~]
└──╼ $pcalc 0y11111111111111111111111111111010 # flip all bits
4294967290 0xfffffffa 0y11111111111111111111111111111010
┌─[student@pc]─[~]
└──╼ $pcalc 0y11111111111111111111111111111010 + 1 # add 1 to that flipped binarry
4294967291 0xfffffffb 0y11111111111111111111111111111011