我很想知道如果给一个无符号变量赋一个负值会发生什么。代码看起来有点像这样。
unsigned int nVal = 0; nVal = -5;
它没有给予我任何编译错误。当我运行程序时,nVal被赋了一个奇怪的值!会不会是某个2的补码值被赋给了nVal?
nVal
svujldwt1#
官方答案-第4.7节conv.integral“如果目标类型是无符号类型,则结果值是与源整数全等的最小无符号整数(模2n,其中n是用于表示无符号类型的位数)。[注意:在二进制补码表示法中,这种转换是概念性的,位模式没有变化(如果没有截断)。-end note ]这实际上意味着,如果底层架构存储的方法不是二进制补码(如带符号幅值或一进制补码),则向无符号的转换必须像二进制补码一样进行。
n
busg9geu2#
它会将表示-5的位模式(2的补码)赋给无符号整型,这将是一个大的无符号值,对于32位整型,这将是2^32 - 5或4294967291
lbsnaicq3#
你是对的,有符号整数以2的补码形式存储,无符号整数存储在unsigned binary representation中。C(和C++)并不区分这两者,所以最终得到的值只是2的补码二进制表示的无符号二进制值。
qxsslcnc4#
它将显示为max unsigned integer - 4值的正整数(值取决于计算机体系结构和编译器)。顺便说一句您可以通过编写一个简单的C++“helloworld”类型程序来检查这一点,并亲自查看
uyhoqukh5#
是的,你说得对。实际赋值类似于设置除第三位以外的所有位。-1表示设置所有位(十六进制:0xFFFFFFFF),-2是除第一位以外的所有位,依此类推。您可能会看到十六进制值0xFFFFFFFB,十进制对应于4294967291。
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
dpiehjr47#
在Windows和Ubuntu Linux中,我已经检查了在C和C++中将任何负数(不仅仅是-1)赋给无符号整数会导致将值UINT_MAX赋给该无符号整数。编译示例link。
-1
UINT_MAX
7条答案
按热度按时间svujldwt1#
官方答案-第4.7节conv.integral
“如果目标类型是无符号类型,则结果值是与源整数全等的最小无符号整数(模2n,其中
n
是用于表示无符号类型的位数)。[注意:在二进制补码表示法中,这种转换是概念性的,位模式没有变化(如果没有截断)。-end note ]这实际上意味着,如果底层架构存储的方法不是二进制补码(如带符号幅值或一进制补码),则向无符号的转换必须像二进制补码一样进行。
busg9geu2#
它会将表示-5的位模式(2的补码)赋给无符号整型,这将是一个大的无符号值,对于32位整型,这将是2^32 - 5或4294967291
lbsnaicq3#
你是对的,有符号整数以2的补码形式存储,无符号整数存储在unsigned binary representation中。C(和C++)并不区分这两者,所以最终得到的值只是2的补码二进制表示的无符号二进制值。
qxsslcnc4#
它将显示为max unsigned integer - 4值的正整数(值取决于计算机体系结构和编译器)。
顺便说一句
您可以通过编写一个简单的C++“helloworld”类型程序来检查这一点,并亲自查看
uyhoqukh5#
是的,你说得对。实际赋值类似于设置除第三位以外的所有位。-1表示设置所有位(十六进制:0xFFFFFFFF),-2是除第一位以外的所有位,依此类推。您可能会看到十六进制值0xFFFFFFFB,十进制对应于4294967291。
zsbz8rwp6#
当你给一个无符号变量赋值一个负值时,它会使用2的补码方法来处理它,在这个方法中,它会把所有的0翻转成1,把所有的1翻转成0,然后加1。在你的例子中,你处理的是4字节(32位)的int,所以它会尝试对32位的数字使用2的补码方法,这会导致高位翻转。例如:
dpiehjr47#
在Windows和Ubuntu Linux中,我已经检查了在C和C++中将任何负数(不仅仅是
-1
)赋给无符号整数会导致将值UINT_MAX
赋给该无符号整数。编译示例link。