Boost logo

Boost :

From: Paul A Bristow (pbristow_at_[hidden])
Date: 2005-12-06 07:28:03


 

| -----Original Message-----
| From: boost-bounces_at_[hidden]
| [mailto:boost-bounces_at_[hidden]] On Behalf Of John Maddock
| Sent: 05 December 2005 11:27
| To: boost_at_[hidden]
| Subject: Re: [boost] [math] floating point classification -
| testinghelpwanted
| I guess if you take epsilon as a measure of error, then the
| worst case, is
| also the usual definition of:
|
| epsilon = 2^(1-D)
|
| If there are D digits in the significand.
|
| But the best case, is the same as the formal definition (the
| difference
| between one and the next representable number),

Then for epsilon 2 ^-105 and 2 ^ -106 are below
outAsHex(one + numeric_limits<quad_float>::epsilon());
// 1.00000000000000000000000000000002 1 == 0x3ff0000000000000
2.4651903288156619e-032 == 0x3960000000000000 2 ^-105
// 1.00000000000000000000000000000001 1==0x3ff0000000000000
1.2325951644078309e-032==0x3950000000000000 2 ^ -106

I note that the 2 ^ -106 value is the one I would naively expect - a single
least significant bit different.

I also feel it is absurd for a value for epsilon to be so much smaller than
for a proper IEEE quad (128-bit) as used by Sparc? which would surely obey
the 2^(1-significands) formula.

| So take your pick :-)

SO I don't pick min or denorm_min ;-)

But I getting further, perhaps terminally, confused by using BOOST unit test
and getting message like this:

BOOST_CHECK_SMALL((one + numeric_limits<quad_float>::epsilon()) - one,
epsilon); // Check epsilon with value 'by definition'
// absolute value of (one + numeric_limits<quad_float>::epsilon()) -
one{0.123259516440783094595582588325435e-31} exceeds
0.123259516440783094595582588325435e-31

Note values appear to be the same, but are one is said to exceed the other!

If display in hex as well, they seem to be identical bit patterns.

outAsHex(one + numeric_limits<quad_float>::epsilon() - one); //
0.246519032881566189191165176650871e-31 2.4651903288156619e-032 ==
0x3960000000000000 0 == 0x0000000000000000
outAsHex(numeric_limits<quad_float>::epsilon()); //
0.246519032881566189191165176650871e-31
2.4651903288156619e-032==0x3960000000000000 0==0x0000000000000000

But both these tests check OK.
BOOST_CHECK((one + numeric_limits<quad_float>::epsilon()) != one); // Check
epsilon with value 'by definition'
BOOST_CHECK((one + numeric_limits<quad_float>::epsilon()) >= one); // Check
epsilon with value 'by definition'
                
So I am puzzled if this is a result of the bizarre properties of
doubledouble, or a problem in BOOST_CHECK_SMALL, or my understanding of it.

Note that in std::numeric_limits, I have added

static const int max_digits10 = 33; // maximum significant decimal digits.

to ensure enough decimal digits are shown, but in any case they are shown in
hex too.

Paul

-- 
Paul A Bristow
Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB
Phone and SMS text +44 1539 561830, Mobile and SMS text +44 7714 330204
mailto: pbristow_at_[hidden]  http://www.hetp.u-net.com/index.html
http://www.hetp.u-net.com/Paul%20A%20Bristow%20info.html

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