c++ 如果我给一个无符号变量赋一个负值会发生什么?

lpwwtiir  于 2022-12-15  发布在  其他
关注(0)|答案(7)|浏览(315)

我很想知道如果给一个无符号变量赋一个负值会发生什么。
代码看起来有点像这样。

unsigned int nVal = 0;
nVal = -5;

它没有给予我任何编译错误。当我运行程序时,nVal被赋了一个奇怪的值!会不会是某个2的补码值被赋给了nVal

svujldwt

svujldwt1#

官方答案-第4.7节conv.integral
“如果目标类型是无符号类型,则结果值是与源整数全等的最小无符号整数(模2n,其中n是用于表示无符号类型的位数)。[注意:在二进制补码表示法中,这种转换是概念性的,位模式没有变化(如果没有截断)。-end note ]
这实际上意味着,如果底层架构存储的方法不是二进制补码(如带符号幅值或一进制补码),则向无符号的转换必须像二进制补码一样进行。

busg9geu

busg9geu2#

它会将表示-5的位模式(2的补码)赋给无符号整型,这将是一个大的无符号值,对于32位整型,这将是2^32 - 5或4294967291

lbsnaicq

lbsnaicq3#

你是对的,有符号整数以2的补码形式存储,无符号整数存储在unsigned binary representation中。C(和C++)并不区分这两者,所以最终得到的值只是2的补码二进制表示的无符号二进制值。

qxsslcnc

qxsslcnc4#

它将显示为max unsigned integer - 4值的正整数(值取决于计算机体系结构和编译器)。
顺便说一句
您可以通过编写一个简单的C++“helloworld”类型程序来检查这一点,并亲自查看

uyhoqukh

uyhoqukh5#

是的,你说得对。实际赋值类似于设置除第三位以外的所有位。-1表示设置所有位(十六进制:0xFFFFFFFF),-2是除第一位以外的所有位,依此类推。您可能会看到十六进制值0xFFFFFFFB,十进制对应于4294967291。

zsbz8rwp

zsbz8rwp6#

当你给一个无符号变量赋值一个负值时,它会使用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
dpiehjr4

dpiehjr47#

在Windows和Ubuntu Linux中,我已经检查了在C和C++中将任何负数(不仅仅是-1)赋给无符号整数会导致将值UINT_MAX赋给该无符号整数。
编译示例link

相关问题