Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ integer overflow

I'm just starting to teach myself C++, and have begun learning about integer overflow. Out of curiosity I wrote some tests just to see what occurs with certain integer values.

Here's my program:

#include <iostream>

int main()
{
    int x(0);
    std::cout << x << std::endl;

    x = x + 2147483647;
    std::cout << x << std::endl;

    x = x + 1;
    std::cout << x << std::endl;
    std::cout << std::endl;

    unsigned int y(0);
    std::cout << y << std::endl;

    y = y + 4294967295;
    std::cout << y << std::endl;

    y = y + 1;
    std::cout << y << std::endl;
}

And here's the output:

0
2147483647
-2147483648

0
4294967295
0

The output surprised me a bit, and I'm wondering if someone could explain why this happened, OR if the unexpected-ness of these results is expected; so this may just be the result of my specific machine.

like image 634
Zack Downs Avatar asked Mar 24 '15 14:03

Zack Downs


People also ask

What happens if integer overflow in C?

Integer Overflow is a phenomenon that occurs when the integer data type cannot hold the actual value of a variable. Integer Overflow and Integer Underflow in C, do not raise any errors, but the program continues to execute (with the incorrect values) as if nothing has happened.

Does C have integer overflow?

(Arithmetic) Integer Overflows An integer overflow occurs when you attempt to store inside an integer variable a value that is larger than the maximum value the variable can hold. The C standard defines this situation as undefined behavior (meaning that anything might happen).

How do I fix integer overflow?

In languages where integer overflow can occur, you can reduce its likelihood by using larger integer types, like Java's long or C's long long int. If you need to store something even bigger, there are libraries built to handle arbitrarily large numbers.

What happens when integer overflows?

An integer overflow can cause the value to wrap and become negative, which violates the program's assumption and may lead to unexpected behavior (for example, 8-bit integer addition of 127 + 1 results in −128, a two's complement of 128).


2 Answers

Signed integer overflow is undefined behaviour, while unsigned integer overflow is well-defined; the value wraps around. In other words, the value is modulo divided by 2bits, where bits is the number of bits in the data type. Since you've a 32-bit int

4294967295 + 1 = 4294967296 % 232 = 0

it results in 0 in the second case. The first case, from the language standpoint, is undefined.

However, most implementations employ 2's complement to implement signed integer types. A toy, signed 4-bit data type, implemented using 2's complement may be used to explain what happend in the first case. In this type

POS_MAX = 7 = 0111)2

NEG_MAX = -8 = 1000)2

The type can hold 24 = 16 states, 8 positive (0 to 7) and 8 negative (-1 to -8).

POS_MAX + 1 = 0111)2 + 1)2 = 1000)2

Since the first bit is set, it's a negative number, to find the actual value, do the inverse the two's complement (subtract 1 and flip bits)

1000)2 - 1)2 = 0111)2

~0111)2 = 1000)2 = 8

Thus the final value is -8. All this is not defined by the language but this is what happened in your case, specifically.

like image 95
legends2k Avatar answered Sep 29 '22 23:09

legends2k


Integers (generally) take a 32-bit representation. If you have 32 bits, you can address from 0 to 231-1. i.e.,

00000000000000000000000000000000
00000000000000000000000000000001
.
.
.
01111111111111111111111111111111
^-------------------------------
signed bit

0 indicates a positive number, 1 indicates a negative number.

If you add 1 to 01111111111111111111111111111111, you get 10000000000000000000000000000000, which is -2147483648 in decimal.

Using an unsigned integer, there's no signed bit and, ipso facto, can have a number twice as large as your largest signed integer. However, when the number rolls over again (i.e., 11111111111111111111111111111111 + 00000000000000000000000000000001), you simply roll back to 00000000000000000000000000000000.

For a more in depth understanding, you can look at two's complement, which is how integers are represented in computers.

like image 30
erip Avatar answered Sep 30 '22 01:09

erip