I'm just curious about what is happening under-the-hood and I can't seem to find the relevant part of the JLS to explain it.
Henry Wong wrote:
I'm just curious about what is happening under-the-hood and I can't seem to find the relevant part of the JLS to explain it.
The floating point formats (and behavior) is not defined in the JLS. Java uses the IEEE standard for floating points -- 32 bit and 64 bit standard.
Henry
Steve
Justin May wrote:But when you do math with that number, the messiness can't be ignored and it often messes up the values in the first 15 decimal places.
I am afraid that isn't correct. You cannot be sure even that there are fifteen correct decimal sig. fig. in a double represented in decimal. The problem becomes particularly bad with small magnitude (absolute value) numbers, smaller than this. When you get down to the smallest subnormal numbers, you cannot necessarily rely on finding the first decimal digit correct.Justin May wrote:. . . the first 15 decimal places are guaranteed to be correct
Campbell's JShell wrote:jshell> Double.MIN_VALUE
$5 ==> 4.9E-324
jshell> Double.MIN_VALUE * 1.4
$6 ==> 4.9E-324
jshell> Double.MIN_VALUE * 1.5
$7 ==> 9.9E-324
It is not the language that decides how to display a double, but methods, including this one. It tells you that it prints as many digits as are necessary to distinguish a number from other numbers (i.e. adjacent values).. . . So Java automatically truncates double values to the first 15 decimal places when displaying them. . . .
The problem becomes particularly bad with small magnitude (absolute value) numbers, smaller than this.
How many digits must be printed for the fractional part of m or a? There must be at least one digit to represent the fractional part, and beyond that as many, but only as many, more digits as are needed to uniquely distinguish the argument value from adjacent values of type double. That is, suppose that x is the exact mathematical value represented by the decimal representation produced by this method for a finite nonzero argument d. Then d must be the double value nearest to x; or if two double values are equally close to x, then d must be one of them and the least significant bit of the significand of d must be 0.
Justin May wrote:Why does that make System.out.print(0.900000000000009) output 0.900000000000009 but System.out.print(0.9000000000000009) outputs 0.9 ?
Justin May wrote:What does it mean for a value to "uniquely distinguish [itself] from an adjacent value of type double" ? Why is 0.900_000_000_000_000_9 adjacent to 0.9 but 0.900_000_000_000_009 is not adjacent to 0.9?
Justin May wrote:In binary they are:
0 01111111110 1100110011001100110011001100110011001100110011001101 // 0.9
0 01111111110 1100110011001100110011001100110011001100110011010101 // 0.900_000_000_000_000_9
0 01111111110 1100110011001100110011001100110011001100110100011110 // 0.900_000_000_000_009
Justin May wrote:That sounds more complicated than "the first 15 decimal places" for sure, but what does it actually mean? Why does that make System.out.print(0.9) output 0.9 instead of 0.90000000000000002220446049250313080847263336181640625 ?
Did you see how Paul cut 87% off of his electric heat bill with 82 watts of micro heaters? |