The 2021 Common Weakness Enumeration lists down "dangerous software weaknesses" that can lead to serious flaws in the final product. One of the items on their top 25 list is the 'Integer Overflow or Wraparound' problem. An integer overflow can eventually cause unexpected behavior like data corruption, infinite loops, unresponsive system or a complete software failure. It is important that all programmers understand this issue and take measures to avoid situations that lead to this runtime error.
Integer overflows occur when we try to store a value that is outside the range of an integer variable that it is designed to hold. While there are many references to 'integer underflow', the Wikipedia article recommends using the term 'underflow' for floating point numbers only. However, we'll discuss what is commonly meant by this terminology and go into details of integer overflow and underflow, which situations can lead to these errors and what possible steps can be taken to prevent such errors.
What Is Integer Overflow?
Integer overflow or wraparound occurs when we store a value that is larger than the space available for storing this value.
A Simple Example
A simple example can be understood by considering an char
variable in Java. Java reserves 16 bits for the char
variable, so it can store values ranging from 0 to 65535. In the code below, we'll display the value of the variable as an integer to see exactly what it is storing.
1var a;
2a = 0xffff; //Set all bits to 1
3console.log("Original: " + a);
4a++;
5console.log("After increment: " + a);
The output you'll see is:
1Original: 65535
2After increment: 0(base)
A programmer not aware of this problem was expecting the variable a
set to 65536. Instead, a wrap around
occurred.
What Is A WrapAround?
Let's understand what is going on when arithmetic is performed on integers. When a=65535, the 16 bit variable stores this in binary as: 0b1111111111111111
(or 0xffff in hex). When a one is added to this, the correct result would be 0b10000000000000000
in binary (or 0x010000). However, only the 16 least significant bits would be stored, so the most significant bit containing the one is lost and we are left with all zeros; and hence the final result we see is 0. This is known as a wraparound problem resulting from the loss of the most significant digits of the result of an arithmetic operation.
To know the exact result stored in an integer variable from a wraparound when value 'v' is stored in an integer variable, which is n bits long, the following formula can be used:
1result stored from overflow = v modulo 2^n
If v
is in the range of the variable, the result stored would be v
, otherwise it is reduced to the last n least significant bits.

Signed Vs. Unsigned Confusion
Another major issue is the signed vs. unsigned type mixup. There are no unsigned types in Java, but other languages like C++ support them. Let's look at the example below, where we have a byte type variable x
. The byte data type in Java is 8 bits and supports a range from -128 to +127. Any programmer can easily fall into the trap by not considering that half the range belongs to negative number and half of it is reserved for positive numbers.
1var x = 127;
2console.log("Original: " + x);
3x++;
4if (x > 127) x -= 256; // Simulate byte overflow
5console.log("After increment: " + x);
The output is:
1Original: 127
2After increment: -128
Again, here we can see that adding one to 127 has led to a value of -128. Here, the reason is the way negative numbers are stored. The binary number 0b10000000
is actually the representation of -128. If the most significant bit is one, then the number is a negative number.

Integer Underflow
Normally, integer underflow refers to storing a value which is too small and falls outside the range allowed by the space reserved for that variable. An example is shown below:
1var x = -128;
2console.log("Original: " + x);
3x--;
4if (x < -128) x += 256; // Simulate byte underflow
5console.log("After decrement: " + x);
The output of the code is shown below:
1Original: -128
2After decrement: 127
This is also wraparound, but in the opposite direction. Now the value has wrapped around towards a large positive value when trying to store a smaller value (-129) outside the range of the byte type variable (-128 to 127). To see why we have a +127, you can apply rules for integer subtraction. To do x-y, we take the two's complement of y and add it to x. Hence:
1Binary representation of x: 0b10000000
2Two's complement of 1 is: 0b11111111
3Add x and two's complement of 1: 0b101111111
4Actual Result stored by taking the 8 least significant bits: 0b01111111

Consequences Of Integer OverFlow/Underflow
The following can be the consequences of the integer overflow, underflow, or wraparound:
- The program will produce inaccurate results from mathematical computations because of integer overflow or underflow
- If a variable is used as a loop control variable with a condition to stop when its value is greater than a fixed value, this condition might never be reached because of integer overflow, resulting in an infinite loop.
- If a variable is used to decide the memory to be allocated to a buffer, a negative value resulting from integer overflow can lead to a system crash.
How to Avoid Integer Overflow/Underflow
The best way to avoid integer overflow or underflow errors is by making sure that the variable used for storing integer values is allocated the right amount of memory. For Java, the following types are available for storing integers:
- Type byte: 8 bits for storing the range -127-128
- Type short: 16 bits for storing the range -32,768 to 32,767
- Type int: 4 bytes for storing the range -2,147,483,648 to 2,147,483,647
- Type long: -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
- Type char: This is used to store characters, but whole numbers from 0 to 65535 can also be stored in this type
Some programming languages allow special data structures to detect integer overflow or underflow. For example, Java 8 includes Math.addExact()
. This method throws an ArithmeticException
when wraparounds occur in integer arithmetic and give programmers a chance to catch such exceptions and take action.

Concluding Remarks
Integer overflow and underflow occur when an integer arithmetic operation results in a value that lies outside the range of the values that can be stored in that variable. The least significant bits resulting from the operation are stored in the variable and the most significant bits are lost. The term wraparound is used to refer to this behavior.
Integer overflow and underflow can lead to dangerous software errors. Programmers should be aware of such runtime errors and take all possible measures to circumvent them.
One Pager Cheat Sheet
- The 2021 Common Weakness Enumeration highlights 'Integer Overflow or Wraparound' as a serious software flaw, caused by attempting to store a value outside the range of an integer variable, leading to unexpected system behavior or failure; understanding and preventing such
runtime errors
is crucial for programmers. - Integer overflow or wraparound happens when a value larger than the maximum capacity of its storage space is stored, often causing unexpected results or errors due to the loss of significant bits; this is typically illustrated in programming languages like Java, where a
char
variable (16 bits) wraps from 65535 to 0 or abyte
variable (8 bits) from 127 to -128, indicating a problem especially prominent with signed vs. unsigned types. - Integer underflow refers to storing a value too small for the range allowed by its variable, resulting in a
wraparound
where the value shifts towards a large positive number. - Integer overflow/underflow can lead to inaccurate mathematical computations, infinite loops, and system crashes, but can be avoided by correctly allocating memory to integer variables or using special data structures like
Math.addExact()
inJava 8
to detect and handle such instances. - Integer overflow and underflow, which cause valuable data loss through a process called
wraparound
, can lead to dangerous software errors; thus, programmers should proactively prevent these runtime errors.