Daryle Walker schrieb:

> On Sunday, August 17, 2003, at 10:33 PM, Paul A. Bristow wrote:
>
> [SNIP]
> > But you are right that it would be better to check that
> > numeric_limits::digits exists and isn't something silly before using
> > the formula.  With all the built-in floating point types it should be
> > fine, and for other (well) User defined floating point types too.  (I
> > will look at this).
> [TRUNCATE]
>
> I think you need to check numeric_limits::radix since your algorithm
> had a base-2-to-10 conversion (the type may not actually be binary!).
> The algorithm was based off a paper about IEEE-754; if IEEE-754 is a
> requirement, you may have to check for that too (via
> numeric_limits::is_iec559).  Remember that even the built-in
> floating-point types aren't guaranteed to match IEEE-754!

I think, the correct solution would be the usage of a constant, similar to
DECIMAL_DIG, which is provided from C99 on. 5.2.4.2.2 says:

"� number of decimal digits, n, such that any floating-point number in the widest
supported floating type with pmax radix b digits can be rounded to a
floating-point
number with n decimal digits and back again without change to the value,

 pmax log10 b if b is a power of 10
 Ceil(1 + pmax log10 b) otherwise

DECIMAL_DIG 10"

(I used Ceil here instead of its symbolic representations. The final value is the
minimum
value, the C++ implementation has to guarantee)

Reasoning:
1) DECIMAL_DIG itself does not depend on IEEE-754 and includes the definition
presented by Paul A. Bristow as a quote from the Kahan paper.
2) Even *printf and strtod in C99 show some dependency on DECIMAL_DIG, in
its "Recommended practice" section.

For *printf:

"For e, E, f, F, g, and G conversions, if the number of significant decimal digits
is at most
DECIMAL_DIG, then the result should be correctly rounded.240) If the number of
significant decimal digits is more than DECIMAL_DIG but the source value is
exactly
representable with DECIMAL_DIG digits, then the result should be an exact
representation with trailing zeros. Otherwise, the source value is bounded by two
adjacent decimal strings L < U, both having DECIMAL_DIG significant digits; the
value
of the resultant decimal string D should satisfy L <= D <= U, with the extra
stipulation that
the error should have a correct sign for the current rounding direction."

Footnote 240): "For binary-to-decimal conversion, the result format�s values are
the numbers representable with the
given format specifier. The number of significant digits is determined by the
format specifier, and in
the case of fixed-point conversion by the source value as well."

and for strtod:

"If the subject sequence has the decimal form and at most DECIMAL_DIG (defined in
<float.h>) significant digits, the result should be correctly rounded. If the
subject
sequence D has the decimal form and more than DECIMAL_DIG significant digits,
consider the two bounding, adjacent decimal strings L and U, both having
DECIMAL_DIG significant digits, such that the values of L, D, and U satisfy L <= D
<= U.
The result should be one of the (equal or adjacent) values that would be obtained
by
correctly rounding L and U according to the current rounding direction, with the
extra
stipulation that the error with respect to D should have a correct sign for the
current
rounding direction.251)"

Footnote 251: "DECIMAL_DIG, defined in <float.h>, should be sufficiently large
that
L and U will usually round to the same internal floating value, but if not will
round to adjacent values."

My personal opinion is: Extend the DECIMAL_DIG definition for any floating point
type,
similar to digits10 it could be part of numeric_limits (if the standard would be
extended) or
from some boost::traits class. The name of the static constant of type int could
be decimal_digits
or so.

Greetings from Bremen,

Daniel Spangenberg




_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to