Open In App

How to Avoid Integer Overflows and Underflows in C++?

Last Updated : 06 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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.

  1. The integer overflow occurs when a number is greater than the maximum value the data type can hold.
  2. 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:

  1. signed int: The signed int data type ranges between -2,147,483,648 to 2,147,483,647 (-109 to 109).
  2. unsigned int: The unsigned int data type ranges between 0 to 4,294,967,295.
  3. 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;
}


Output

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;
}


Output

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;
}


Output

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;
}


Output

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;
}


Output

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;
}


Output

-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;
}


Output

-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;
}


Output

-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;
}


Output

-10000000000


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads