How to Avoid Integer Overflows and Underflows in C++?
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; } |
The 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; } |
The 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; } |
The 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; } |
The 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; } |
4294967295
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; } |
-1
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; } |
-1410065408
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; } |
-10000000000
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; } |
-10000000000
Please Login to comment...