# Boost :

From: Paul A Bristow (pbristow_at_[hidden])
Date: 2005-12-04 18:10:34

Doh! Of course previous with deliberate mistake hangs...

But this looks more sensible, but final eps shown is still zero.

{
quad_float eps = one;
do {
eps /= two;
onepluseps = one + eps;
}
while (onepluseps != one);
return eps + eps;

gives

float:
sizeof(float) = 4
epsilon(float) = 1.19209e-007
std::numeric_limits<float>::epsilon() = 1.19209e-007

double:
sizeof(double) = 8
epsilon(double) = 2.22045e-016
std::numeric_limits<double>::epsilon() = 2.22045e-016

long double: ,, MSVC == double
sizeof(long double) = 8
epsilon(long double) = 2.22045e-016
std::numeric_limits<long double>::epsilon() = 2.22045e-016

epsilon(quad_float) = 0 <<<<<<<<<<<< also zero
std::numeric_limits<quad_float>::epsilon() = 0.2465190329e-31 << my
'guess'

A little debugging shows

eps {hi=4.9303806576313238e-032 lo=0.00000000000000000 oprec=10 }

eps {hi=1.2325951644078309e-032 lo=0.00000000000000000 oprec=10 }

eps {hi=9.881312916825e-324#DEN lo=0.00000000000000000 oprec=10 }

at loop count 1075, eps == zero and

onepluseps {hi=1.0000000000000000 lo=4.940656458412e-324#DEN oprec=10

Note lo double has become denormalised.

So what is the right value of epsilon - or rather the 'useful' value of eps?

Paul

| Darwin long double is really a doubledouble - I think, so really a UDT,
for
| which getting the right type is critical? NTL quad_float is the same - I
think.

| | -----Original Message-----
| | From: boost-bounces_at_[hidden]
| | [mailto:boost-bounces_at_[hidden]] On Behalf Of Matthias Troyer
| | Sent: 04 December 2005 19:45
| | To: boost_at_[hidden]
| | Subject: Re: [boost] [math] floating point classification -
| | testinghelpwanted
| |
| |
| | On Dec 3, 2005, at 8:09 PM, John Maddock wrote:
| |
| | >> 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?
| |
| | Since i asked the students in my class to write a program
| | calculating
| | the machine epsilon as a homework, I just ran our solution
| | (posted at
| | http://www.itp.phys.ethz.ch/lectures/PT/Exercises/Uebung1/Solution/
| | eps.cpp). Please overlook that the code is ugly, and does not
| | use any
| | templates - they just had one week of C++ training. Anyway, this code:
| |
| |
| | long double epsilon_long_double() {
| | long double eps = 1.;
| | long double onepluseps;
| |
| | do {
| | eps /= 2;
| | onepluseps = 1. + eps;
| | } while ( onepluseps != 1.);
| |
| | return 2*eps;
| |
| | }
| |
| |
| | returns 0, hence there is really the problem that
| | numeric_limits<long double>::epsilon() == numeric_limits<long
double>::min()
| |
| | Matthias