Babu said:
And as to which of the two presumbtions is correct (point (a) or (b) in
Chris's post), I think it is case (a) - which can be verified by
creating BigDecimals from the two doubles and checking which is nearer
to 1E-21.
For completeness:
The "correct" answer is (of course):
1 / (10 ** 21)
The answer given by pow() is, decoding the bits of the double:
5316911983139664 / (2 ** 122)
The value of 1.0e-21D is (again decoding the bits of the double):
5316911983139663 / (2 ** 122)
The same three values in decimal format (fully expanded):
exact: 0.000 000 000 000 000 000 001
pow(): 0.000 000 000 000 000 000 001 000 000 000 000 000
095 616 548 359 462 372 671 727 780 467 234 839
207 896 907 042 893 985 817 499 924 451 112 747
192 382 812 5
1e-21: 0.000 000 000 000 000 000 000 999 999 999 999 999
907 537 452 227 896 371 396 729 934 511 675 530
756 910 417 959 359 982 376 099 651 446 565 985
679 626 464 843 75
The exact answer is not exactly representable as a Java double, but lies
between the answer given by pow() and the value of 1.0e-21D. If you do the
arithmetic, you'll see that the exact value actually lies slightly closer to
the value of 1.0e-21D (by about 3%), so pow() is not answering the closest
possible double to the mathematically correct answer. So in that sense the
answer is "wrong", and Chris's option (a) holds. However I wouldn't follow him
in calling pow() "broken" since it is actually returning the /second/ closest
double to the correct answer (the one just above rather than the one just
below), and that is acceptable according the contract of pow() since it is
within one "ulp" of the mathematically correct answer.
-- chris