我很好奇如果将负值赋给无符号变量会发生什么。
代码大致如下。
unsigned int nVal = 0;
nVal = -5;
编译没有出错。但是当我运行程序时,nVal
被赋予了一个奇怪的值!是否可能将一些二进制补码值分配给nVal
?
我很好奇如果将负值赋给无符号变量会发生什么。
代码大致如下。
unsigned int nVal = 0;
nVal = -5;
编译没有出错。但是当我运行程序时,nVal
被赋予了一个奇怪的值!是否可能将一些二进制补码值分配给nVal
?
对于官方答案,请参考第4.7节 conv.integral
如果目标类型是无符号的,那么结果值就是源整数模2n的最小无符号整数余数(其中
n
是用于表示无符号类型的位数)。[注:在二进制补码表示中,这种转换是概念性的,并且如果没有截断,则位模式不会改变。——末尾注释]
这意味着,如果底层架构使用的方法不是二进制补码(例如有符号幅度或反码),则转换为无符号类型时必须表现得好像它是二进制补码。
这将把表示-5的二进制补码赋给无符号整数(unsigned int),它将成为一个较大的无符号值。对于32位整数而言,这将是2的32次方减去5,即4294967291。
ceil(log_2(x))
的简写。) - GManNickG它会显示为一个正整数,其值为最大无符号整数 - 4(值取决于计算机架构和编译器)。
顺便说一下, 您可以通过编写一个简单的C++“hello world”类型程序来检查并亲自验证。
是的,你说得对。实际分配的值类似于除了第三位之外所有位都设置为1。-1表示所有位都设置为1(十六进制:0xFFFFFFFF),-2表示除了第一位之外的所有位等等。你可能会看到的是十六进制值0xFFFFFFFB,它在十进制中对应4294967291。
┌─[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
在我检查过的Windows和Ubuntu Linux中,将任何负数(不仅仅是-1
)分配给C和C++中的无符号整数会导致将值UINT_MAX
分配给该无符号整数。
编译示例link。
nVal = (unsigned int) -5;
。将-5
强制转换为unsigned int
在 6.3.1.3 中有定义。2的补码表示在标准中没有强制规定,但是将其转换为无符号数的算法是:“通过反复加上或减去新类型中可以表示的最大值再加一来将该值转换为新类型范围内的值。” - Pascal Cuoq