简体   繁体   中英

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: 在此处输入图片说明

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:

在此处输入图片说明

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

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 2 971 .

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 2 970 , but 2 969 has no effect.

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

1.7976931348623157E308

And

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

Infinity

It looks like 2 970 gets rounded up to 2 971 to get added to Double.MAX_VALUE , but 2 969 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.

These "weird" results are not really specific to Java. It's just that floats as defined by the relevant IEEE standard, are much more complicated than most people suspect. But onto your specific results: Float.MIN_VALUE is the smallest positive float, so it's very close to 0. Hence Float.MIN_VALUE - 1 will be very close to -1. But since the float precision around -1 is greater than that difference, it comes out as -1. As to Float.MAX_VALUE , the float precision around this value is much greater than 1 and adding one doesn't change the result.

your results aren't necessarily out of the ordinary, it's just that floats in general are very specific and your request is very close. I have had similar problems while using double data types. Just double check to make sure that your code checks out with what you were expecting.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM