Reputation: 2261
I wrote this piece of code just to see what would happen if I put a negative integer into an unsigned integer array.
#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;
}
I was expecting integer overflow to occur in both the cases. However, only in the second case that actually happened. In the first case, everything behaved as if it were an oridinary integer array, not an unsigned integer array. So what exactly is happening that's causing this anomalous behaviour. My compiler is gcc 4.8 in cases that's of any importance. Thank you for your help. EDIT: Here's th output on my computer
8
4294967294
Upvotes: 4
Views: 9535
Reputation: 279255
Converting -2
to unsigned int
results in the value 4294967294
(since unsigned int
is 32 bits in the C++ implementation you're using).
unsigned int
arithmetic is carried out modulo 4294967296
(or in general UINT_MAX+1
). Hence in unsigned int
, 4 + 4 + 2 + 4294967294 is 8.
Technically according to the standard this is not called "overflow", because the standard defines the result to depend only on the value of UINT_MAX
. Overflow is the undefined behavior when signed integer arithmetic exceeds its bounds.
Upvotes: 1
Reputation: 799
There is an integer overflow. Here is the reason ( the numbers are converted to unsigned int)
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
Upvotes: 8
Reputation: 9380
For the signed integers, the last bit is used to hold the sign value. So in your case, when you assign a negative integer to an unsigned integer, the last bit is taken up to represent the number rather than the sign value.
Negative numbers are usually represented in 2's complement form. So
11111110 is represented as −1 if signed
11111110 is represented as 254 if unsigned
Upvotes: 1
Reputation: 20631
You're seeing the result of (defined) unsigned integer overflow. Your -2 value becomes a very large unsigned integer, which when added to another unsigned integer, causes an overflow (the result is larger than the largest possible unsigned int
value) with the effect that the result is 2 smaller than the other unsigned integer.
Eg:
unsigned int a = -2;
unsigned int b = 4;
unsigned int c = a + b; // result will be 2!
Upvotes: 0
Reputation: 217293
when you do (assuming unsigned int is uint32_t):
array[0] = 4;
array[1] = 4;
array[2] = 2;
array[3] = -2; // You store 4294967294 here
And here array[0] + array[1] + array[2] + array[3]
is equal to 4294967304
which don't fit in an uint32_t 0x1 0000 0008
which result in 8
.
Upvotes: 1
Reputation: 5387
For signed integer, 31st bit is treated as sign bit (assuming 4 byte is integer size). For unsigned integers, there is no sign bit at all, i.e. each bit is contributes to the absolute value
Upvotes: 0