我很想知道如果我给一个无符号变量赋一个负值会发生什么。
该代码将看起来像这样。
unsigned int nVal = 0;
nVal = -5;
它没有给我任何编译器错误。当我运行程序时,它nVal
被分配了一个奇怪的值!可能是某些2的补码值分配了nVal
吗?
我很想知道如果我给一个无符号变量赋一个负值会发生什么。
该代码将看起来像这样。
unsigned int nVal = 0;
nVal = -5;
它没有给我任何编译器错误。当我运行程序时,它nVal
被分配了一个奇怪的值!可能是某些2的补码值分配了nVal
吗?
nVal = (unsigned int) -5;
。的演员-5
来unsigned int
被定义在6.3.1.3。标准不要求以2s补码表示。但是要转换为无符号的算法是:“通过重复添加或减去比新类型可以表示的最大值多一的值来转换值,直到该值在范围内为止。的新类型。”
Answers:
官方答案-4.7转换积分
“如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(取模2 n,其中n
n
是用于表示无符号类型的位数)。[注意:在二进制补码形式中,此转换是概念性的,并且位模式没有任何变化(如果没有截断的话)。
从本质上讲,这意味着,如果基础体系结构存储的方法不是Two's Complement(如符号幅度或One's Complement),则到无符号的转换必须表现为好像是Two's Complement。
它将代表-5(以2的补码表示)的位模式分配给无符号的int。这将是一个很大的无符号值。对于32位整数,这将是2 ^ 32-5或4294967291
ceil(log_2(x))
。)
是的,你是对的。分配的实际值类似于除第三个位以外的所有其他位。-1是设置的所有位(十六进制:0xFFFFFFFF),-2是除第一个以外的所有位,依此类推。您将看到的可能是十六进制值0xFFFFFFFB,其十进制对应于4294967291。
当您为无符号变量赋负值时,它使用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