Re: Double type precision in java



John Ersatznom wrote:

Now, there are, oddly, some -0.0s in the lists output. I'd guess it was
actually a subnormal -0.00000...0001 internally (and it's NOT always
outputting enough digits to exactly read it back in) except that many of
those are definitely products of power-of-2-denominator rationals -- in
fact, integers to the last one. Those shouldn't lose precision (unless
the numerator gets too big).

I don't think the representation of -0.0 is any kind of an issue here (-0.0 has
a perfectly good FP representation all of its own, so an "approximate" internal
representation is neither necessary nor permitted). To see a simpler version
of the same test that displays the same behaviour without any zeros:

public class Test
{
public static void
main(String[] args)
{
System.out.println(0.1D);
System.out.println(2.1D - 2.0D);
}
}

Which produces the output:
0.1
0.10000000000000009

(In this case the sum in the second println() is actually evaluated by the
compiler rather than at runtime, but that makes no difference to the
behaviour).


One way to think of why this happens:

The value 2.1 when represented as 64-bit floating point is "rounded" to the
nearest binary value, as it happens this is the value which (if printed at
perfect precision) would be
2.100000000000000088817841970012523233890533447265625
(That is just one a range of real numbers which all have the same
representation as a double, but it is the only one from that which is exactly
representable as a double).

Similarly the most precise representation of 2.0 is
2.
(;-)

But that of the result of the calculation (2.1 - 2.0) is:
0.100000000000000088817841970012523233890533447265625

For comparison, that of 0.1 is
0.1000000000000000055511151231257827021181583404541015625

Note the difference. This is part of the reason for the unexpected (by the OP)
results, and is also the reason why (2.1 - 2.0) != 0.1.

Also, when Java prints the double values, it chooses the real number with the
shortest string representation from the range of reals which all map the
same double value. In this case the nearest to:
0.100000000000000088817841970012523233890533447265625

is:
0.1

Whereas the nearest to:
0.1000000000000000055511151231257827021181583404541015625
is:
0.10000000000000009

Hence the output of the test program.

-- chris



.



Relevant Pages

  • Re: The spinoza papers: design of the extra-precision number object 2
    ... I'm interested in the rationale behind representing integers and reals ... This has an interesting consequence in that the representation ... Which is why real numbers are represented in "arbitrary precision" ... As to "nonterminating" operations as an objection. ...
    (comp.programming)
  • Re: ptr conversions and values
    ... members of one set with members of the other set. ... characteristics of the representation are in many ways quite different ... > Integers and pointers are like objects living in different worlds. ... > representation as an array of two reals, ...
    (comp.std.c)
  • Re: ptr conversions and values
    ... >> Joining them in pairs is called mapping, ... precision complex number can have the same representation as a double. ... whereas any connection between memory locations and integers is a part ... > it attaches a meaning of a complex number to an array of two reals, ...
    (comp.std.c)
  • Re: The common usage of "nonnegative real number" is ludicrous.
    ... you're talking about representations of the reals. ... qualities which are sign and magnitude. ... representation is somehow fundamental and inherent ... the tradition without peering beneath the ...
    (sci.math)
  • Re: Is continuum completely filled up?
    ... Does not this property include the fact that reals have cardinality of power ... In any representation, these operations /must/ be understood as part ... involve /writing out/ the sum, digit by digit, of the decimal ... Rationals are build from naturals. ...
    (sci.math)