Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overflow and Underflow in Java Float and Double Data Types

I have created the following code to test Float and Double Java numeric data types for underflow and overflow:

// Float Overflow & Underflow
float floatTest = Float.MAX_VALUE;
floatTest++;
out.println("Float Overflow: " + Float.MAX_VALUE + " + 1 = " + floatTest);
floatTest = Float.MIN_VALUE;
floatTest--;
out.println("Float Underflow: " + Float.MIN_VALUE + " - 1 = " + floatTest);
out.println("");

// Double Overflow & Underflow
double doubleTest = Double.MAX_VALUE;
doubleTest++;
out.println("Double Overflow: " + Double.MAX_VALUE + " + 1 = " + doubleTest);
doubleTest = Double.MIN_VALUE;
doubleTest--;
out.println("Double Underflow: " + Double.MIN_VALUE + " - 1 = " + doubleTest);
out.println("");

Can someone explain the weird values I see in the result: enter image description here

When I do the similar test (code below) with byte, short, int and long:

// BYTE Overflow & Underflow
byte byteTest = Byte.MAX_VALUE;
byteTest++;
out.println("Byte Overflow: " + Byte.MAX_VALUE + " + 1 = " + byteTest);
byteTest = Byte.MIN_VALUE;
byteTest--;
out.println("Byte Underflow: " + Byte.MIN_VALUE + " - 1 = " + byteTest);
out.println("");

// SHORT Overflow & Underflow
short shortTest = Short.MAX_VALUE;
shortTest++;
out.println("Short Overflow: " + Short.MAX_VALUE + " + 1 = " + shortTest);
shortTest = Short.MIN_VALUE;
shortTest--;
out.println("Short Underflow: " + Short.MIN_VALUE + " - 1 = " + shortTest);
out.println("");

// INTEGER Overflow & Underflow
int intTest = Integer.MAX_VALUE;
intTest++;
out.println("Integer Overflow: " + Integer.MAX_VALUE + " + 1 = " + intTest);
intTest = Integer.MIN_VALUE;
intTest--;
out.println("Integer Underflow: " + Integer.MIN_VALUE + " - 1 = " + intTest);
out.println("");

// LONG Overflow & Underflow
long longTest = Long.MAX_VALUE;
longTest++;
out.println("Long Overflow: " + Long.MAX_VALUE + " + 1 = " + longTest);
longTest = Long.MIN_VALUE;
longTest--;
out.println("Long Underflow: " + Long.MIN_VALUE + " - 1 = " + longTest);
out.println("");

The results look as expected:

enter image description here

Can someone explain overflow and underflow in Java float and double and why am I seeing above results?

like image 439
jjj Avatar asked Oct 28 '25 14:10

jjj


1 Answers

Floating Point Overflow

Adding 1 to Double.MAX_VALUE OR Float.MAX_VALUE doesn't represent enough of a value to avoid getting rounded down due to precision error. At Double.MAX_VALUE, the difference between consecutive values, due to there being 53 bits for mantissa, is quite large.

System.out.println("Math.ulp(Double.MAX_VALUE) is " + Math.ulp(Double.MAX_VALUE));

1.9958403095347198E292

This value is 2971.

You need to add an expression that yields at least this much to overflow to Infinity. I say "yields at least this much" because I can get this to overflow by adding 2970, but 2969 has no effect.

doubleTest += Math.pow(2.0, 969);

1.7976931348623157E308

And

doubleTest += Math.pow(2.0, 970);

Infinity

It looks like 2970 gets rounded up to 2971 to get added to Double.MAX_VALUE, but 2969 gets rounded down to 0 and has no effect on the sum.

A similar process is occurring for float, though the values aren't nearly so high.

Floating Point Underflow

doubleTest = Double.MIN_VALUE;
doubleTest--;

This is just an infinitesimal value minus one, which is practically minus one. This not underflow.

Underflow occurs when the exponent, not the value, gets too low to be represented, so 0.0 results. Divide by 2 instead to get underflow.

doubleTest = Double.MIN_VALUE;
doubleTest /= 2;

0.0

Integer/Long Overflow/Underflow

Those are the expected values because you know the values "wrap around" to the other side of the range of values.

like image 194
rgettman Avatar answered Oct 31 '25 03:10

rgettman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!