2

I am writing a java program. When I do 4.9E-324/2, it returns 0.0. Using BigDecimal returns the correct value. Am I missing something?

double x = 4.9E-324/2.0; 
System.out.println(x); //result is zero
System.out.println(BigDecimal.valueOf(4.9E-324).divide(BigDecimal.valueOf(2.0)).toPlainString()); //result is a non-zero value
khelwood
  • 55,782
  • 14
  • 81
  • 108
Arwa Reaz
  • 31
  • 1
  • 2
  • 1
    It looks like you've discovered the whole reason that `BigDecimal` exists; to wit, `double` does not have arbitrary precision. – azurefrog Nov 04 '17 at 23:08
  • 2
    I strongly disagree with the choice of duplicate question. That question covers the common question of why doubles can't represent numbers like `5.6` exactly, but it says nothing about the minimum positive value for a `double`, which is what this question is about. I'll reopen this unless someone else can explain why this is an appropriate duplicate. – ajb Nov 04 '17 at 23:33

2 Answers2

3

The defintion of Double.MIN_VALUE gives the answer. This is the smallest positive value that a double can hold, equal to 2-1074, which is about 4.94 * 10-324. If you put 4.9E-324 in your program, it's close enough to MIN_VALUE that the compiler will round up and use this value. But then when you divide by 2, the result is too small for a double, so it is rounded down to 0.

The reason 2-1074 is the smallest value has to do with the format of 64-bit floating-point numbers specified by IEEE 754. This is a standard format, and most processors have built-in hardware to perform calculations on numbers in that format. (By contrast, BigDecimal is represented as a Java array of unlimited length, so it's able to handle numbers with much greater precision; however, arithmetic on these numbers is done in software, making it much slower than calculations on doubles.) A 64-bit double consists of a sign bit, an 11-bit exponent field, and a 52-bit mantissa. For a "normal" value, the exponent field is in the range 1 to 2046, and the actual exponent (power of 2) is offset from this so that the exponent ranges from -1022 to 1023. The mantissa is 1.xxxxx...xxx (in binary), where the x's are the 52 bits of the mantissa. The value represented by this format is 1.xxxxx...xxx * 2exponent. So the smallest normal value is 1 * 2-1022, or Double.MIN_NORMAL. If the exponent field is 0, and the mantissa bits are not all zero, then the floating-point value is a "denormal" number whose value is 2-1022 * 0.xxxxx...xxx, where the x's are the 52-bit mantissa field. (Denormal numbers can get smaller than normal ones, but they don't have 52 bits of precision like normal doubles do.) The smallest possible value is thus 2-1022 * 0.00000...001; the last part of this expression is 2-52 since the mantissa field is 52 bits long, so that makes the smallest value 2-(1022+52) = 2-1074.

ajb
  • 31,309
  • 3
  • 58
  • 84
1

This is because 4.9E-324 is less than the 4.94065645841246544e-324d limit that a double has for decimal values.

A BigDecimal can hold many more digits, so it works there.

Maicon Mauricio
  • 2,052
  • 1
  • 13
  • 29
iPhoenix
  • 719
  • 7
  • 20