How to Avoid Integer Overflows and Underflows in C++?
Last Updated :
06 Apr, 2023
Integers in C++ are allocated with a certain number of bits. If an integer value, takes more bits than the allocated number of bits, then we may encounter an overflow or underflow.
- The integer overflow occurs when a number is greater than the maximum value the data type can hold.
- The integer underflow occurs when a number is smaller than the minimum value the data type can hold.
We deal mainly with these data types to store integers in C++. These are:
- signed int: The signed int data type ranges between -2,147,483,648 to 2,147,483,647 (-109 to 109).
- unsigned int: The unsigned int data type ranges between 0 to 4,294,967,295.
- long long: The long long data type ranges between -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 (-1018 to 1018).
Let's discuss integer overflow and integer underflow in detail.
Integer Overflow
Example: In the below C++ program, three variables a, b and c are initialized as int(signed) data type:
C++
// C++ program to demonstrate
// integer overflow
#include <iostream>
using namespace std;
// Driver code
int main()
{
int a = 100000;
int b = 100000;
int c = a * b;
cout << "The product of a and b is " <<
c << endl;
return 0;
}
OutputThe product of a and b is 1410065408
Time Complexity : O(1)
Auxiliary Space : O(1)
Explanation: The expected value of c is 1010 but the output is 1410065408. This is because int c can store a maximum range of 109.
Solution 1:
1. Initialize variable c as long long data type.
long long c = a * b;
2. But the problem still arises because a and b are int data types and the product of two int data types is always an integer ranges between the range of int which is mentioned above.
3. Initialize a or b as long long data types. Since multiplication of int and long long is long long. So, a and b will result in a long long range.
Below is the C++ program to implement the above solution to handle integer overflow:
C++
// C++ program to handle integer
// overflow
#include <iostream>
using namespace std;
// Driver code
int main()
{
int a = 100000;
// Changed int b to long long b
long long b = 100000;
long long c = a * b;
cout << "The product of a and b is " <<
c << endl;
return 0;
}
OutputThe product of a and b is 10000000000
Solution 2:
1. Initialize variable c as long long data type.
long long c = a * b;
2. Instead of changing the data types of a and b, we can multiply a and b with 1LL while initializing the value of c so that multiplication of a and b with long long 1 also results into long long and that value will be stored in long long c.
Below is the C++ program to implement the above solution to handle integer overflow:
C++
// C++ program to handle integer
// overflow
#include <iostream>
using namespace std;
// Driver code
int main()
{
int a = 100000;
int b = 100000;
// Here we multiplied 'a' with 1LL
// which results into long long
// which is further multiplied with 'b'
long long c = a * 1LL * b;
cout << "The product of a and b is " <<
c << endl;
return 0;
}
OutputThe product of a and b is 10000000000
Solution 3: Initialize all three variables a, b and c as long long data types initially. It will give our desired output but it will take some extra space.
Below is the C++ program to implement the above solution to handle integer overflow:
C++
// C++ program to handle integer
// overflow
#include <iostream>
using namespace std;
// Driver code
int main()
{
// Here we changed the data types
// of both a and b to long long
// to avoid overflow
long long a = 100000, b = 100000;
long long c = a * b;
cout << "The product of a and b is " <<
c << endl;
return 0;
}
OutputThe product of a and b is 10000000000
Integer Underflow
Example 1: In the below code, 3 variables a, b and c are initialized then as unsigned int to show integer underflow:
C++
// C++ program to show integer
// underflow
#include <iostream>
using namespace std;
// Driver code
int main()
{
unsigned int a = 4, b = 5;
unsigned int c = a - b;
cout << c;
return 0;
}
Explanation:
The expected value of c is -1 but the output is 4294967295. This is because unsigned int c cannot store a negative value.
Solution 1:
To fix the above problem initialize c as int(signed) to store a negative number. Below is the C++ program to show how to handle integer underflow:
C++
// C++ program to show how to
// handle integer underflow
#include <iostream>
using namespace std;
// Driver code
int main()
{
unsigned int a = 4, b = 5;
// Here we changed data type of
// c to signed int
int c = a - b;
cout << c;
return 0;
}
Example 2: In the below code, variable a is initialized as unsigned int, b, and c are initialized as int to show integer underflow:
C++
// C++ program to show integer
// underflow
#include <iostream>
using namespace std;
// Driver code
int main()
{
unsigned int a = 1000000;
int b = -10000;
int c = b * a;
cout << c;
return 0;
}
Explanation:
The expected value of c is -1010 but the output is -1410065408. This is because, int(signed) c cannot store a negative value smaller than -2,147,483,648.
Solution 1:
1. Initialize variable c as long long data type to store -1010.
long long c = b * a;
2. But the problem still arises as you can see below because a is a unsigned int while b is a signed int and the product of both of them cannot be a number in the range of long long, so we need to change one of them to a long long data type.
Below is the C++ program to handle integer underflow:
C++
// C++ program to handle
// integer underflow
#include <iostream>
using namespace std;
// Driver code
int main()
{
unsigned int a = 1000000;
long long b = -10000;
long long c = b * a;
cout << c;
return 0;
}
Solution 2:
Instead of changing data types of a and b, we can multiply a and b with 1LL while initializing the value of c so that multiplication of a and b with long long 1 also results into long long and that value will be stored in long long c.
C++
// C++ program to handle
// integer underflow
#include <iostream>
using namespace std;
// Driver code
int main()
{
unsigned int a = 1000000;
int b = -10000;
long long c = b * 1LL * a;
cout << c;
return 0;
}
Similar Reads
How Do I Detect Unsigned Integer Overflow in C++?
In C++, unsigned integer is a datatype that can store only zero and non-negative integer values. According to C++ standard, unsigned integer overflow is defined behavior (as it wraps around using modulo arithmetic and starts again from 0). So, to detect when this wrapping occurred is important to de
3 min read
How to Count Set Bits in an Integer in C++?
In binary representation of a number, a set bit is defined as the binary digit (bit) that is set to 1. In this article, we will learn how to count the set bits in a given integer in C++.ExampleInput: 13Output:The number of set bits in 13 (1101) is: 3Counting Set Bits in an IntegerTo count the set bi
2 min read
How to Round a Double to an int in C++?
In C++, the double data type is used to store floating-point numbers with double precision. In this article, we will learn how to round a double value to an int in C++. Example: Input: double val= 2.6 Output: Integer for double value 2.5 is: 3 Rounding a Double to an Int in C++To round a double valu
2 min read
How to Take Operator as Input in C++?
Operators are symbols that specify some kind of operation. In C++, we sometimes need to take operators as user input mainly to perform mathematical operations. In this article, we will learn how to take operators as user input in C++. Operators as Input in C++To take operators (like +,-,*,/ etc) as
2 min read
How Do Sequence Points Relate to Undefined Behaviour in C++?
In C++, sequence points are used to determine the order of evaluation of expressions to avoid undefined behavior in our programs. In this article, we will learn how do sequence points relate to undefined behavior in C++. What are Sequence Points in C++?In C++, sequence points define the order in whi
5 min read
How to Create Vectors of Unique Pointers in C++?
In C++, the vector is defined as a dynamic array that can grow or shrink in size. Vectors of unique pointers are commonly used to manage the collections of dynamically allocated objects as they combine the dynamic resizing capability of vectors with the automatic memory management provided by unique
2 min read
How to Ask User Input Until Correct Input is Received?
User input is a common source of errors in C++ programs so itâs important to validate user input to make the program more reliable. In this article, we will discuss how to ask the user for input until valid input is received in our C++ program. For Example, Input: asdf Output: Incorrect Input. Pleas
2 min read
How to Overload the (+) Plus Operator in C++?
In C++, operator overloading is a feature of the OOPs concept that allows you to redefine the behavior for different operators when they are used with objects of user-defined classes. The plus operator (+) is a binary operator generally used for addition. In this article, we will learn how to overlo
2 min read
How to Assign Negative Infinity in C++?
In C++, the infinity is written as inf. We get infinity as a result when a positive number is divided by a null value or when a value is much greater and cannot be stored in 64-bit. In C++, positive infinity is defined in many libraries but the negative infinity is not defined. In this article, we w
2 min read
How to Overload the Less-Than (<) Operator in C++?
In C++ we have an operator called less than operator (<) which checks if the left side operand is smaller than the right side operand or not. In this article, we will learn how to overload the less-than operator in C++. Overloading Less-Than Operator in C++In C++, we can overload the less-than op
2 min read