|
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