Boost logo

Boost :

From: Paul A Bristow (pbristow_at_[hidden])
Date: 2005-12-04 09:43:49


 

| -----Original Message-----
| From: boost-bounces_at_[hidden]
| [mailto:boost-bounces_at_[hidden]] On Behalf Of John Maddock
| Sent: 03 December 2005 19:09
| To: boost_at_[hidden]
| Subject: Re: [boost] [math] floating point classification -
| testinghelpwanted
|
| > ld = hi + low as above is not among the bit patterns he lists as
| > valid. If you apply the definition of epsilon to the "normal" long
| > doubles only, then you get a value like the one Paul
| Bristow computed
| > for NTL's quad_float.
|
| I agree: that explanation is quite explicit when it says it
| follows Kahan's
| "double double" and the IEEE spec. So the low part must be
| normalised so
| that it's bit's "follow on" from those in the high part. As
| it stands,
| 1+numeric_limits<>::epsilon() should evaluate to 1, but we
| really need to
| check this out. Does anyone of a numerical inclination, want
| to run some tests on Darwin?

Am I right in concluding that Darwin is same as Keith Briggs doubledouble
and NTL?

http://www.cs.cornell.edu/Info/People/vavasis/qmg2.0/patch2_files/doubledoub
le2.h

and www.shoup.net/ntl/ gives references to doubledouble and quad_float.

For NTL quad_float, using my 'guess' at epsilon.

using NTL::quad_float;
static quad_float epsilon() throw() { return
2.4651903288156618919116517665087069677288E-32;}; // 2^(1-106) == 2^105

0.246519032881566189191165176650871e-31 2.4651903288156619e-032 ==
0x3960000000000000 0 == 0x0000000000000000

1 + epsilon is
1.00000000000000000000000000000002 1 == 0x3ff0000000000000
2.4651903288156619e-032 == 0x3960000000000000

So ls digits is 2 - twice what I would expect.

What I get from my nextafter(1) function is

1.00000000000000000000000000000001 1 == 0x3ff0000000000000
1.2325951644078309e-032 == 0x3950000000000000

Note now get a 1 as the least significant bit.

So, perhaps naively, I suspect my epsilon is twice as big as it should be.

quad_float one;
one = to_quad_float("1.");
BOOST_CHECK(one + numeric_limits<quad_float>::epsilon() == one);

./unitTestFunc2.cpp(556): error in "log10_test_function": check one +
numeric_limits<quad_float>::epsilon() == one failed

as I would expect.

I'd also like to have nextafter (and the other IEEE recommended) for
quadfloat.

My tentative stab at nextafter for quad_float is

quad_float nextafter(const quad_float& x, double y =
numeric_limits<double>::max())
{ // Change by one unit in last place (least significant bit), default
increases.
        // Might check that x (and y) are finite?
        // What about sign of x and y?
        double direction = (x < y) ? +numeric_limits<double>::max() :
-numeric_limits<double>::max();
        // If x < y then increment by one ulp, else decrement.
        quad_float temp = x;
        if (temp.lo == numeric_limits<double>::max())
        { // nextafter would overflow.
                temp.lo = 0.;
                temp.hi = std::tr1::nextafter(temp.hi, direction);
        }
        else
        { // Normal case.
                temp.lo = std::tr1::nextafter(temp.lo, direction);
        }
        return temp;
} // quad_float nextafter(const quad_float& x)

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