# Boost :

From: Paul A. Bristow (boost_at_[hidden])
Date: 2002-09-06 18:48:12

Thanks to Gaby for these useful references to Floating point formats.

>
http://www.tru64unix.compaq.com/docs/base_doc/DOCUMENTATION/V51_HTML/ARH9LBT
E/FLTNGCHP.HTM#fp-fmt-fig

Under the expert guidance of Sylvain Pion [Sylvain.Pion_at_[hidden]]

I have used NTL, an arbitrary precision to calculate the EXACT
representations
of the intervals of pi for float, double and long double.

As he has eventually persuaded me, it seems necessary to meet the
requirements
of the C++ Standard [2.13.3.1] which says :

" [...] If the scaled value is in the range of representable values for its
type, the result is the scaled value if representable else the larger or
smaller representable value nearest the scaled value, chosen in an
implementation-defined manner. [...] "

to provide sufficient decimal digits = number of significand bits.
These have effectively infinite trailing zeros.

(In practice these don't seem to matter beyond the significant_digits10,
a few more than digits10, give by the formula given by Kahan.
But it might... so for full portability ...)

for 24 bit significand formats:

static const float pi_f_l = 13176794.0f/(1 << 22)
static const float pi_f_u = 13176795.0f/(1 << 22);

or more simply

static const float pi_f_l = 3.141592502593994140625;
static const float pi_f_u = 3.1415927410125732421875;

for double 53 bit significand formats:

static const double pi_d_l =
3.141592653589793115997963468544185161590576171875;
static const double pi_d_u =
3.141592653589793560087173318606801331043243408203125;

pi_d_l = 0x400921fb54442d18
pi_d_u = 0x400921fb54442d19
pi_d = 0x400921fb54442d18 - same as lower interval.

and long double 64 bit significand formats:

static const long double pi_l_l = 14488038916154245684.0l/(1 << 62);
static const long double pi_l_u = 14488038916154245685.0l/(1 << 62);

or to avoid your complex format and choking the compiler

static const long double pi_l_l2 =
3.141592653589793238295968524909085317631252110004425048828125;
static const long double pi_l_u2 =
3.14159265358979323851280895940618620443274267017841339111328125;

(These actual values are unchecked as yet!)

Values can be calculated for all useful significands -
mainly IEEE and VAX formats - and selected somehow,
switch or macro as discussed by several people,
using numeric_limits<>::digits, and also radix if desired.
(Are there really any machines using radix other than 2 that we need to
cater for?)

I am warming to the idea of adding intervals
for ALL the math constants discussed previously.
Both the math constants and the interval library
will be VERY MUCH more useful if these are available.

Does this seem a reasonable scheme?

Paul

Dr Paul A Bristow, hetp Chromatography
Prizet Farmhouse, Kendal, Cumbria, LA8 8AB UK
+44 1539 561830 Mobile +44 7714 33 02 04
mailto:pbristow_at_[hidden]