Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java's '==' operator on doubles

This method returns 'true'. Why ?

public static boolean f() {
   double val = Double.MAX_VALUE/10;
   double save = val;
   for (int i = 1; i < 1000; i++) {
       val -= i;
   }
   return (val == save);
}
like image 828
amitooshacham Avatar asked Feb 06 '13 16:02

amitooshacham


People also ask

Can we use modulo operator with double?

Double Modulus OperatorIf either or both operands of the mod operator have type double, then evaluating it produces the remainder. This kind of mod operator does not exist in C or C++ where the mod operator only works with int operands. The evaluated result is a double value.

Does modulo work with doubles in Java?

Since we're using the double data type, modulus won't work on floating-point numbers. For example, 0.5 % 0.3 should return 0.2, but I'm getting a division by zero exception.

How do you find the remainder of a double?

Syntax : double remainder(double a, double b) float remainder(float a, float b) long double remainder(long double a, long double b) Parameter: a and b are the values of numerator and denominator. Return: The remainder() function returns the floating point remainder of numerator/denominator rounded to nearest.

How are doubles represented in Java?

The double covers a range from 4.94065645841246544e-324d to 1.79769313486231570e+308d (positive or negative). Its default value is 0.0d. Its default size is 8 byte. It is the default type for decimal numbers.


2 Answers

You're subtracting quite a small value (less than 1000) from a huge value. The small value is so much smaller than the large value that the closest representable value to the theoretical result is still the original value.

Basically it's a result of the way floating point numbers work.

Imagine we had some decimal floating point type (just for simplicity) which only stored 5 significant digits in the mantissa, and an exponent in the range 0 to 1000.

Your example is like writing 10999 - 1000... think about what the result of that would be, when rounded to 5 significant digits. Yes, the exact result is 99999.....9000 (with 999 digits) but if you can only represent values with 5 significant digits, the closest result is 10999 again.

like image 122
Jon Skeet Avatar answered Sep 21 '22 00:09

Jon Skeet


When you set val to Double.MAX_VALUE/10, it is set to a value approximately equal to 1.7976931348623158 * 10^307. substracting values like 1000 from that would required a precision on the double representation that is not possible, so it basically leaves val unchanged.

Depending on your needs, you may use BigDecimal instead of double.

like image 32
Cyrille Ka Avatar answered Sep 21 '22 00:09

Cyrille Ka