Boost logo

Boost :

From: Herve Bronnimann (hbr_at_[hidden])
Date: 2002-09-06 17:11:25


On Fri, Sep 06, 2002 at 03:39:57PM -0400, Sylvain Pion wrote:
> The naive approach (which I guess is what you had in mind) is to use a RUN-TIME
> algorithm, and make it dump enough precision in decimal (e.g. Maple), and just
> use this.
> But this DOES NOT work : it is not reliable enough given the precise
> constraints that I have given.
> Read again my quote of the C++ standard from [2.13.3.1].
> The key remark in this paragraph is that if the decimal scaled value is NOT
> representable (which is what you highly probably get with the naive approach),
> then the necessary rounding which is done by the compiler at compile-time is
> implementation-defined. So, as I want to be sure of the correct FP values that
> I get, I need to fall back on a decimal value which is EXACTLY representable
> in the compiler's FP format (which I can know via numeric_limits::digits and
> radix). Which is what led me to my proposal : testing in a compile-time switch
> (several ?: ) using numeric_limits::digits (and this method should also switch
> on radix to be complete).

Just occured to me: If you want to take advantage of compile-time,
template arguments of the form <unsigned int> would work, and
specializations for various ints would give you the desired rounding.

Example (the constants are bogus, but you'll get my point):

     template <unsigned int decimal_precision>
     struct interval_pi {
       static const double lower = 3; // default version
       static const double upper = 4;
     };
     
     #define BOOST_INTERVAL_SPECIALIZE_PI_CONSTANT(n, l, u) \
       template <> struct interval_pi<n> { \
         static const double lower = l; \
         static const double upper = u; \
       }
     
     BOOST_INTERVAL_SPECIALIZE_PI_CONSTANT(1, 3.1 , 3.2 );
     BOOST_INTERVAL_SPECIALIZE_PI_CONSTANT(2, 3.14 , 3.15 );
     BOOST_INTERVAL_SPECIALIZE_PI_CONSTANT(3, 3.141 , 3.142 );
     BOOST_INTERVAL_SPECIALIZE_PI_CONSTANT(4, 3.1415 , 3.1416 );
     BOOST_INTERVAL_SPECIALIZE_PI_CONSTANT(5, 3.14159 , 3.14160 );
     BOOST_INTERVAL_SPECIALIZE_PI_CONSTANT(6, 3.1415926 , 3.1415927 );
     BOOST_INTERVAL_SPECIALIZE_PI_CONSTANT(7, 3.14159265 , 3.14159266 );
     BOOST_INTERVAL_SPECIALIZE_PI_CONSTANT(8, 3.141592653 , 3.141592654 );
     BOOST_INTERVAL_SPECIALIZE_PI_CONSTANT(9, 3.1415926535 , 3.1415926536 );

     std::cout << interval_pi<7>::lower << std::endl;

You can go on to provide all the (precomputed) precisions ever needed by
users. It's a little less flexible than switches ( ? : ) but it's
perhaps more readable... ?

-- 
Herve'

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