C++ 如果将负值赋给无符号变量会发生什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2711522/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:26:49  来源:igfitidea点击:

What happens if I assign a negative value to an unsigned variable?

c++type-conversionintegerunsignedsigned

提问by ckv

I was curious to know what would happen if I assign a negative value to an unsigned variable.

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

The code will look somewhat like this.

代码看起来有点像这样。

unsigned int nVal = 0;
nVal = -5;

It didn't give me any compiler error. When I ran the program the nValwas assigned a strange value! Could it be that some 2's complement value gets assigned to nVal?

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

采纳答案by Dennis Zickefoose

For the official answer - Section 4.7 conv.integral

对于官方答案 - 第 4.7 节conv.integral

"If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2nwhere nis the number of bits used to represent the unsigned type). [ Note: In a two's complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). —end note ]

“如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模 2 n,其中n是用于表示无符号类型的位数)。[注意:在二进制补码表示中,此转换是概念性的,位模式没有变化(如果没有截断)。--尾注]

This essentially means that if the underlying architecture stores in a method that is not Two's Complement (like Signed Magnitude, or One's Complement), that the conversion to unsigned must behave as if it was Two's Complement.

这实质上意味着,如果底层架构存储在不是二进制补码的方法中(如有符号幅度或一个补码),则转换为无符号的行为必须表现得好像它是二进制补码一样。

回答by Jasmeet

It will assign the bit pattern representing -5 (in 2's complement) to the unsigned int. Which will be a large unsigned value. For 32 bit ints this will be 2^32 - 5 or 4294967291

它会将表示 -5(以 2 的补码形式)的位模式分配给 unsigned int。这将是一个很大的无符号值。对于 32 位整数,这将是 2^32 - 5 或 4294967291

回答by perimosocordiae

You're right, the signed integer is stored in 2's complement form, and the unsigned integer is stored in the unsigned binary representation. C (and C++) doesn't distinguish between the two, so the value you end up with is simply the unsigned binary value of the 2's complement binary representation.

没错,有符号整数以 2 的补码形式存储,符号整数以无符号二进制表示形式存储。C(和 C++)不区分两者,因此您最终得到的值只是 2 的补码二进制表示的无符号二进制值。

回答by Dror Helper

It will show as a positive integer of value of max unsigned integer - 4 (value depends on computer architecture and compiler).

它将显示为最大无符号整数值的正整数 - 4(值取决于计算机体系结构和编译器)。

BTW
You can check this by writing a simple C++ "hello world" type program and see for yourself

顺便说一句,
您可以通过编写一个简单的 C++“hello world”类型程序来检查这一点,并亲自查看

回答by Martin

Yes, you're correct. The actual value assigned is something like all bits set except the third. -1 is all bits set (hex: 0xFFFFFFFF), -2 is all bits except the first and so on. What you would see is probably the hex value 0xFFFFFFFB which in decimal corresponds to 4294967291.

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

回答by Zafeer

When you assign a negative value to an unsigned variable then it uses the 2's complement method to process it and in this method it flips all 0s to 1s and all 1s to 0s and then adds 1 to it. In your case, you are dealing with int which is of 4 byte(32 bits) so it tries to use 2's complement method on 32 bit number which causes the higher bit to flip. For example:

当您为无符号变量分配负值时,它使用 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