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