如果我为无符号变量赋值为负值会怎样?

时间:2010-04-26 06:42:57

标签: c++ type-conversion integer unsigned signed

我很想知道如果我给无符号变量分配负值会发生什么。

代码看起来有点像这样。

unsigned int nVal = 0;
nVal = -5;

它没有给我任何编译器错误。当我运行程序时,nVal被分配了一个奇怪的值!是否可以将某个2的补码值分配给nVal

6 个答案:

答案 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