
Boost : 
From: Guillaume Melquiond (gmelquio_at_[hidden])
Date: 20030620 15:04:53
On Fri, 20 Jun 2003, Gennaro Prota wrote:
> >>  [*] 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 don't know either. What I know is the way floating literals should
> work:
>
> A floating literal consists of an integer part, a decimal point,
> a fraction part, an e or E, an optionally signed integer exponent,
> and an optional type suffix. [...]
> If the scaled value is in the range of representable values for its
> type, the result is the scaled value if representable, else the
> larger or smaller representable value nearest the scaled value,
> chosen in an implementationdefined manner.
I know this part of the standard. But it doesn't apply in the situation I
was describing. I was describing the case of a constant whose decimal (and
consequently binary) representation is not finite. It can be an irrational
number like pi; but it can also simply be a rational like 1/3.
When manipulating such a number, you can only give a finite number of
decimal digit. And so the phenomenon of double rounding I was describing
will occur since you first do a rounding to have a finite number of
digits and then the compiler do another rounding (which is described by
the part of the standard you are quoting) to fit the constant in
the floatingpoint format.
Just look one more time at the example I was giving in the previous mail.
> Of course "the nearest" means nearest to what you've actually written.
> Also, AFAICS, there's no requirement that any representable value can
> be written as a (decimal) string literal. And, theoretically, the
I never saw any computer with unrepresentable values. It would require it
manipulates numbers in a radix different from 2^p*5^q (many computers use
radix 2, and some of them use radix 10 or 16; no computer imo uses radix
3).
> "chosen in an implementationdefined manner" above could simply mean
> "randomly" as long as the fact is documented.
The fact that it does it randomly is another problem. Even if it was not
random but perfectly known (for example roundtonearesteven like in the
IEEE754 standard), it wouldn't change anything: it would still be a
second rounding. As I said, it is more of an arithmetic problem than of a
compilation problem.
> Now, I don't even get you when you say "more digits than necessary".
What I wanted to say is that writing too much decimal digits of a number
doesn't improve the precision of the constant. It can degrade it due to
the double rounding. In conclusion, when you have a constant, it is better
to give an exact representation of the nearest floatingpoint number
rather than writing it with 40 decimal digits. By doing that, the compiler
cannot do the second rounding: there is only one rounding (the one you
did) and you are safe.
> One thing is the number of digits you provide in the literal, one
> other thing is what can effectively be stored in an object. I think
> you all know that something as simple as
>
> float x = 1.2f;
> assert(x == 1.2);
>
> fails on most machines.
Yes, but it's not what I was talking about. I hope it's a bit more clear
now.
Guillaume
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk