|
Boost : |
From: Guillaume Melquiond (gmelquio_at_[hidden])
Date: 2003-06-20 11:30:48
On Fri, 20 Jun 2003, Paul A Bristow wrote:
[snip]
> | [*] It is not even true. Due to "double rounding" troubles,
> | using a higher precision can lead to a value that is not the
> | nearest number.
>
> Is this true even when you have a few more digits than necessary?
> Kahan's article suggested to me that adding two guard decimal digits
> avoids this problem. This why 40 was chosen.
I don't know if we are speaking about the same thing. I am not sure I will
be clear if I try to explain it directly so I will just give an example.
The number are supposed to be stored in decimal in order to clarify the
reasoning (it also works with binary constants, juste replace non-zero
digits by some 1).
the constant is 1.00050001236454786005785305678....
you write it with 7 seven digits: 1.000500
the floating-point format only uses 4 digits
so the compiler rounds the number to: 1.000 (round-to-nearest-even)
but the nearest value was: 1.001 (since the constant is > 1.0005)
I hope it was clear enough. If you use more digits than necessary, the
value you finally obtain may not be the nearest one. And it doesn't have
anything to do with the compiler, with the number of digits used, with the
radix, etc.
With the most common constants and formats, I don't think the problem
arises. But it is still possible: a string of zeros at the wrong place is
enough (and when the only digits are 0 and 1, it is not that uncommon to
get such a string).
> Consistency is also of practical importance - in practice, don't all
> compilers read decimal digit strings the same way and will end up with
> the same internal representation (for the same floating point format),
> and thus calculations will be as portable as is possible? This is
> what causes most trouble in practice - one gets a slightly different
> result and wastes much time puzzling why.
This problem doesn't depend on the compiler. If all the compilers read
digit strings the same way and apply the same kind of rounding, they will
all fail the same way. It is an arithmetic problem, not a compilation
problem.
> | So maybe the interface should provide four
> | values for each constant at a given
> | precision: an approximation, the nearest value, a lower
> | bound, and an upper bound.
>
> Possible, but yet more complexity?
Yes, but also more correct. Most people will rely on the approximation
(it's the 40 digits values you are providing) to do their computations.
But there may be people who expect to have the nearest value. They will
get it if the library is able to provide it, and will get a compilation
error otherwise. There is absolutely no surprise this way.
Guillaume
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk