Question

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
Was it helpful?

Solution

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

OTHER TIPS

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.

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

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.

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

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!
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top