Overflow, Underflow, Widening and Narrowing in Java

This tutorial explains some of the important concepts related with variables and data types like Overflow, Underflow, Widening and Narrowing in java. These are some useful concepts that a programmer must be aware of.

Overflow and Underflow in Java

Every data type in java has a range of values that can be assigned into the variable of that data type. For example a byte data type variable can store values from -128(min) to 127(max), if you try to store a value which is not in this range then overflow or underflow takes place.

  byte b1 = (byte)128; // Overflow, since assigned value is greater than max range of byte data type 
  byte b2 = (byte)(-129); // Underflow, since assigned value is less than min range of byte data type 

So overflow and underflow in java is a condition when an operation returns a result that crosses the range of data type. If the value crosses the maximum prescribed size of a data type, it is called as Overflow and if the value crosses the minimum prescribed size, it is called as Underflow. Java does not throw any error or exception in any of the above cases.

For example, an int is of 32 bit in Java, any value that crosses 32 bits gets rolled over, which means after incrementing 1 on max value of int(2147483647), the returned value will be -2147483648 which is minimum value of int . Similarly after decrementing 1 from -2147483648, the result will be 2147483647 which is maximum value of int.

For float data types(float and double), overflow will result in infinity while underflow results in 0.0

Overflow and underflow program in Java

 class OverflowAndUnderflow {
   public static void main(String args[]) {
      int intOverflow = 2147483647 + 1;
      System.out.println("int overflowed value = "+ intOverflow);
 
      int intUnderflow = -2147483648 - 1;
      System.out.println("int underflowed value =  "+ intUnderflow);
      // Compilation error in below code, Constant values are checked at compile time for size limit
      // int overflow = 2147483648;  // Crossed maximum prescribed value for int data type
      double doubleOverflow = 1e308 * 10;
      System.out.println("double overflowed value = " + doubleOverflow);
 
      double doubleUnderflow = 4.9e-324 / 100000;
      System.out.println("double underflowed value = " + doubleUnderflow);
    }
 }	

Output:

int overflowed value = -2147483648
int underflowed value = 2147483647
double overflowed value = Infinity
double underflowed value = 0.0

What is the difference between overflow and underflow in java ?

Overflow is the condition when the value that we assign to a variable crosses the maximum range of variable's data type while underflow is the condition when the value that we assign to the variable crosses the minimum range of variable's data type. Refer the example above to understand it via program.

Does overflow and underflow happens with Non Primitive data types as well ?

No, as it doesn't contain value, it contains only reference.

Widening and Narrowing in java

Widening is a process in which a smaller data type value is converted to wider/larger data type value. It is done by java itself that is why we call it implicit/automatic conversion. This is also known as Upcasting. Automatic conversion of a subclass reference variable to a superclass reference variable is also part of widening.

Let's understand this by an example :

  byte b1 = 20;
  int i = b1;

Here in line 2 the byte variable(b1) value is converted into int data type value. This is basically called widening and it is done by java itself. In java, following type of conversion basically comes under widening :

 Widening or Upcasting. It happens automatically(Implicit Conversion)
 byte → short → char → int → long → float → double
Subclass to superclass conversion is also widening. Refer inheritance for subclass/superclass Subclass → Superclass

So if you assign a byte variable into short, char, int, long, float or double variable, it will be widening, similarly assigning any short variable to char, int, long, float or double variable will also be widening and so on. Some specific type of conversion given above may result in loss of precision, refer this link for more information.

Is int to double widening ?

Yes, int to double is widening, since the size of double data type is greater than int data type.

Narrowing is just opposite of widening, it's a process in which a larger data type value is converted to smaller data type value. This is done explicitly by the programmer. This is also known as Downcasting. Explicit conversion of a superclass reference variable to a subclass reference variable is also part of narrowing.

Let's understand this by an example :

  int i = 20;
  byte b1 = (byte)i;

Here in line 2 the int variable(i) value is converted into byte data type value. This is basically called narrowing and it is done explicitly as you can see I have used (byte) before variable i to convert the int value into byte value. In java, following type of conversion basically comes under narrowing :

 Narrowing or Downcasting. It is done Explicitly by the programmer
 double → float → long → int → char → short → byte
Superclass to subclass conversion is also narrowing. Superclass → Subclass

So if you assign a double variable into float, long, int, char, short or byte variable, it will be narrowing, similarly assigning any float variable to long, int, char, short or byte variable will also be narrowing and so on. Narrowing conversion may lose information about the overall magnitude of a numeric value and may also lose precision and range, refer this link for more information.

Widening and narrowing program in Java

 class WideningAndNarrowing {
   public static void main(String [] args) {
      byte b=20;
      int i=b;    //byte to int widening
      long l=b;   //byte to long widening
      double d=b; //byte to double widening
      System.out.println("int value after widening : "+ i);
      System.out.println("long value after widening : "+ l);
      System.out.println("double value after widening : "+ d);

      double d2 =20.5;
      byte b2 = (byte)d2;   //Narrowing double to byte
      // long ll=d2;  //compile time error, must be explicitly casted 
      long l2= (long)d2;    //Narrowing double to long
      float f2= (float)d2;  //Narrowing double to float  
      System.out.println("Narrowing double value to byte : "+ b2);
      System.out.println("Narrowing double value to long : "+ l2);
      System.out.println("Narrowing double value to float : "+ f2);
    }
  }   	

Output:

int value after widening : 20
long value after widening : 20
double value after widening : 20.0
Narrowing double value to byte : 20
Narrowing double value to long : 20
Narrowing double value to float : 20.5

What is the difference between widening and narrowing in java ?

In widening, the smaller data type value is automatically converted/accommodated into larger data type. It happens automatically, that means it is done by java itself. Narrowing is just opposite of widening, in this the larger data type value is converted/accommodated in smaller data type. It needs to be done explicitly by the programmer itself. Refer the example above to understand it via program.

What is type casting in java ?

Widening and narrowing is also known as type casting in java.

★★★
  • Every time you run Overflow or underflow program, it will return same result.
  • Every programming language has it's own way of handling overflow and underflow conditions.
  • Overflow and Underflow deals on min/max values of data types while Widening and Narrowing deals on conversion of data type.