Boost logo

Boost :

From: Daniel Spangenberg (dsp_at_[hidden])
Date: 2003-08-19 03:24:47


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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk