我编写这段代码只是为了看看如果我将负整数放入无符号整数数组中会发生什么。
#include <iostream>
int main()
{
using namespace std;
unsigned int array[4];
array[0]=4;
array[1]=4;
array[2]=2;
array[3]=-2;
cout << array[0] + array[1] + array[2] + array[3] << endl;
unsigned int b;
b=-2;
cout << b <<endl;
return 0;
}
我希望在这两种情况下都会发生整数溢出。但是,仅在实际发生的第二种情况下。在第一种情况下,一切都表现得好像它是一个oridinary整数数组,而不是一个无符号整数数组。那么究竟发生了什么导致了这种异常行为。在任何重要的情况下,我的编译器都是gcc 4.8。谢谢您的帮助。编辑:这是我电脑上的输出
8
4294967294
答案 0 :(得分:8)
存在整数溢出。这是原因(数字转换为无符号整数)
1111 1111 1111 1111 1111 1111 1111 1110 // -2
+0000 0000 0000 0000 0000 0000 0000 0100 //+ 4
-------------------------------------------
0000 0000 0000 0000 0000 0000 0000 0010 //= 2
+0000 0000 0000 0000 0000 0000 0000 0100 //+ 4
-------------------------------------------
0000 0000 0000 0000 0000 0000 0000 0110 //= 6
+0000 0000 0000 0000 0000 0000 0000 0010 //+ 2
-------------------------------------------
0000 0000 0000 0000 0000 0000 0000 1000 //= 8 -> the result
答案 1 :(得分:1)
对于有符号整数,最后一位用于保存符号值。因此,在您的情况下,当您将负整数分配给无符号整数时,最后一位将被用来表示数字而不是符号值。
负数通常以2的补码形式表示。所以
11111110 is represented as −1 if signed
11111110 is represented as 254 if unsigned
答案 2 :(得分:1)
当你这样做时(假设unsigned int是uint32_t):
array[0] = 4;
array[1] = 4;
array[2] = 2;
array[3] = -2; // You store 4294967294 here
此处array[0] + array[1] + array[2] + array[3]
等于4294967304
,不适合uint32_t 0x1 0000 0008
,导致8
。
答案 3 :(得分:1)
将-2
转换为unsigned int
会产生值4294967294
(因为unsigned int
在您正在使用的C ++实现中为32位。
unsigned int
算术以模4294967296
(或一般UINT_MAX+1
)执行。因此在unsigned int
中,4 + 4 + 2 + 4294967294是8。
从技术上讲,根据标准,这不称为“溢出”,因为标准定义的结果仅依赖于UINT_MAX
的值。当有符号整数算术超出其边界时,溢出是未定义的行为。
答案 4 :(得分:0)
对于有符号整数,第31位被视为符号位(假设4字节是整数)。对于无符号整数,根本没有符号位,即每个位都有助于绝对值
答案 5 :(得分:0)
您正在看到(已定义)无符号整数溢出的结果。你的-2值变成一个非常大的无符号整数,当它被添加到另一个无符号整数时,会导致溢出(结果大于最大可能的unsigned int
值)和效果结果比另一个无符号整数小2。
例如:
unsigned int a = -2;
unsigned int b = 4;
unsigned int c = a + b; // result will be 2!