Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Testing for very small doubles with DBL_EPSILON and _isnan()

15 views
Skip to first unread message

Olumide

unread,
Jun 4, 2009, 8:21:30 PM6/4/09
to
Hello,

I recently had a colleague introduce me to the variable macro
DBL_EPSILON and the function _isnan(), because some of my functions
return 1.#QNANO values. However, I'm not sure of of how best to use
DBL_EPSILON and _isnan(). Which is the better way to test for a small
double:

Method 1: _isnan( really_small_double );

Method 2: if( really_small_double < DBL_EPSILON ) // do stuff

Thanks,

- Olumide

Keith Thompson

unread,
Jun 4, 2009, 10:30:04 PM6/4/09
to

Neither.

C99 has a standard macro isnan(); if your implementation doesn't
support it, it might instead have something similar called "_isnan()".
You'll have to consult your implementation's documentation to find out
exactly what it does. But it almost certainly tests whether its
argument is a NaN -- which stands for "Not a Number". It's not a
really small number; it's not a number at all.

DBL_EPSILON is the difference between 1.0 and the next representable
number above 1.0. Whether that qualifies as "really small" is
something you'll have to decide for yourself. It depends on the
requirements of your application. There is no single answer.

Oh, and (x < DBL_EPSILON) is true for very large negative numbers.

I *think* this applies to both C and C++ (I'm reading and posting in
comp.lang.c), but cross-posts between comp.lang.c and comp.lang.c++
are almost never a good idea.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Olumide

unread,
Jun 5, 2009, 7:20:14 PM6/5/09
to
> You misunderstand DBL_EPSILON.  It is not a very small number.  It is
> the smallest number that can be added to 1.0 to produce a result >
> 1.0.  If a double has d digits of precision, then DBL_EPSILON is on
> the order of pow(10,-d).  Almost all floating point representations
> can handle numbers much smaller.

Thanks everyone. I'm sorry I didn't express myself clearly enough. By
"too small" I mean cannot be represented by a double, thus the value
1.#QNANO (BTW, I'm using Visual Studio .NET 2003). Therefore, I meant
to ask what is the proper technique for testing the result of a
computation is not representable as a double?

Thanks.

Pete Becker

unread,
Jun 5, 2009, 7:24:56 PM6/5/09
to
Olumide wrote:
>
> Thanks everyone. I'm sorry I didn't express myself clearly enough. By
> "too small" I mean cannot be represented by a double, thus the value
> 1.#QNANO (BTW, I'm using Visual Studio .NET 2003). Therefore, I meant
> to ask what is the proper technique for testing the result of a
> computation is not representable as a double?
>

There's no such thing as too small to represent as a double. Really
really small values become zero. NaNs come from things like 0/0,
inf-inf, etc.

Try this:

double f = 0.0;
while (f != 0)
{
std::cout << f << std::endl;
/* printf("%f\n", f); for the C cross-post */
f /= 2;
}

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)

Pete Becker

unread,
Jun 5, 2009, 7:34:53 PM6/5/09
to
Pete Becker wrote:
> Olumide wrote:
>>
>> Thanks everyone. I'm sorry I didn't express myself clearly enough. By
>> "too small" I mean cannot be represented by a double, thus the value
>> 1.#QNANO (BTW, I'm using Visual Studio .NET 2003). Therefore, I meant
>> to ask what is the proper technique for testing the result of a
>> computation is not representable as a double?
>>
>
> There's no such thing as too small to represent as a double. Really
> really small values become zero. NaNs come from things like 0/0,
> inf-inf, etc.
>
> Try this:
>
> double f = 0.0;

Whoops:

double f = 1.0;

Olumide

unread,
Jun 5, 2009, 7:54:47 PM6/5/09
to
> > Thanks everyone. I'm sorry I didn't express myself clearly enough. By
> > "too small" I mean cannot be represented by a double, thus the value
> > 1.#QNANO (BTW, I'm using Visual Studio .NET 2003). Therefore, I meant
> > to ask what is the proper technique for testing the result of a
> > computation is not representable as a double?
>
> There's no such thing as too small to represent as a double. Really
> really small values become zero. NaNs come from things like 0/0,
> inf-inf, etc.

Perhaps then the problem is a NaN. My functions perform lots of
computation of the type: a^b, and occasionally, a is a very small
number, while b is negative, so that the result tends to 1/0 . Might
this explain why my function occasionally returns 1.#QNANO?

Thanks.


Keith Thompson

unread,
Jun 5, 2009, 8:50:46 PM6/5/09
to

It's hard to tell.

Is a^b supposed to be a raised to the power b? If so, I'd expect
something like, say, 1e-20 ^ (-100) to yield Infinity, not a NaN.
You'll need to analyze your code, perhaps using a debugger, to
determine where it's going wrong. If you can narrow your code down to
a small self-contained program that exhibits the problem, we can
probably help you -- or, very likely, you'll find the problem yourself
in the process of narrowing it down.

But please decide which language you're using, C or C++, and post just
to the appropriate newsgroup.

Another thing, you see the line "Olumide <50...@web.de> writes:" at
the top? That's an attribution line. Please leave those in place for
any quoted text. Thanks.

Dik T. Winter

unread,
Jun 5, 2009, 9:14:11 PM6/5/09
to
In article <c9c6b947-5a46-4b86...@g20g2000vba.googlegroups.com> Olumide <50...@web.de> writes:
...

> Perhaps then the problem is a NaN. My functions perform lots of
> computation of the type: a^b, and occasionally, a is a very small
> number, while b is negative, so that the result tends to 1/0 . Might
> this explain why my function occasionally returns 1.#QNANO?

No, that would result in an infinity, not in a NAN. The only way that could
yield a NAN would be if a was negative (and with a well-designed library,
b non-integral). In all other cases a number or an infinity should be
returned (with the now common IEEE standard arithmetic).

So I suspect your a has become negative.
--
dik t. winter, cwi, science park 123, 1098 xg amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

Dik T. Winter

unread,
Jun 5, 2009, 9:30:22 PM6/5/09
to
In article <a86cd80f-39b1-4bc7...@21g2000vbk.googlegroups.com> Olumide <50...@web.de> writes:
...

> Thanks everyone. I'm sorry I didn't express myself clearly enough. By
> "too small" I mean cannot be represented by a double, thus the value
> 1.#QNANO (BTW, I'm using Visual Studio .NET 2003). Therefore, I meant
> to ask what is the proper technique for testing the result of a
> computation is not representable as a double?

You misunderstand. A NAN does not mean what you think it means. It means
either that the result is not a real number (but complex, like sqrt(-2.0))
or that the question asked makes no sense (like 0.0/0.0).

The proper way to check for it is to test with an isnan() function, if
available, otherwise the test a != a should yield true for a NAN, but
beware of compilers that are too eager in their optimisation.

Olumide

unread,
Jun 6, 2009, 12:13:10 PM6/6/09
to
On 6 June, 02:14, "Dik T. Winter" <Dik.Win...@cwi.nl> wrote:

> In article <c9c6b947-5a46-4b86-adb6-7921b1e4f...@g20g2000vba.googlegroups.com> Olumide <50...@web.de> writes:
> ...
>  > Perhaps then the problem is a NaN. My functions perform lots of
>  > computation of the type: a^b, and occasionally, a is a very small
>  > number, while b is negative, so that the result tends to 1/0 . Might
>  > this explain why my function occasionally returns 1.#QNANO?
>
> No, that would result in an infinity, not in a NAN.  The only way that could
> yield a NAN would be if a was negative (and with a well-designed library,
> b non-integral).  In all other cases a number or an infinity should be
> returned (with the now common IEEE standard arithmetic).
>
> So I suspect your a has become negative.

Okay, here is a snip of a typical section of code that occasionally
results in a output being 1.#QNANO:

double deltaX, deltaY, deltaZ;
initializeDeltaXYZ( ... );
double r2 = deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
double output = 2 * m_alpha * pow( r2 , m_alpha - 1 ) + 4 * m_alpha *
(m_alpha - 1) * pow( deltaX , 2 ) * pow( r2 , m_alpha - 2 );

What I would like to know is:

1. why output is sometimes evaluated as 1.#QNANO in this case
2. how to test when this happens.

Thanks.

Olumide

unread,
Jun 6, 2009, 12:15:22 PM6/6/09
to
On 6 June, 17:13, Olumide <50...@web.de> wrote:
> Okay, here is a snip of a typical section of code that occasionally
> results in a output being 1.#QNANO:
>
> double deltaX, deltaY, deltaZ;
> initializeDeltaXYZ( ... );
> double r2 = deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
> double output = 2 * m_alpha * pow( r2 , m_alpha - 1 ) + 4 * m_alpha *
> (m_alpha - 1) * pow( deltaX , 2 ) * pow( r2 , m_alpha - 2 );
>
> What I would like to know is:
>
> 1. why output is sometimes evaluated as 1.#QNANO in this case
> 2. how to test when this happens.

I forgot to add, m_alpha is a double, with typical values: 0.5, 1.5 or
2.5

Nate Eldredge

unread,
Jun 6, 2009, 1:33:26 PM6/6/09
to
Olumide <50...@web.de> writes:

> On 6 June, 02:14, "Dik T. Winter" <Dik.Win...@cwi.nl> wrote:
>> In article <c9c6b947-5a46-4b86-adb6-7921b1e4f...@g20g2000vba.googlegroups.com> Olumide <50...@web.de> writes:
>> ...
>> �> Perhaps then the problem is a NaN. My functions perform lots of
>> �> computation of the type: a^b, and occasionally, a is a very small
>> �> number, while b is negative, so that the result tends to 1/0 . Might
>> �> this explain why my function occasionally returns 1.#QNANO?
>>
>> No, that would result in an infinity, not in a NAN. �The only way that could
>> yield a NAN would be if a was negative (and with a well-designed library,
>> b non-integral). �In all other cases a number or an infinity should be
>> returned (with the now common IEEE standard arithmetic).
>>
>> So I suspect your a has become negative.
>
> Okay, here is a snip of a typical section of code that occasionally
> results in a output being 1.#QNANO:
>
> double deltaX, deltaY, deltaZ;
> initializeDeltaXYZ( ... );
> double r2 = deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
> double output = 2 * m_alpha * pow( r2 , m_alpha - 1 ) + 4 * m_alpha *
> (m_alpha - 1) * pow( deltaX , 2 ) * pow( r2 , m_alpha - 2 );

I'd suggest printing the values of all these variables (r2, m_alpha, and
all the deltas) before the computation of `output'. That will probably
bring enlightenment.

> What I would like to know is:
>
> 1. why output is sometimes evaluated as 1.#QNANO in this case
>
> 2. how to test when this happens.

As mentioned earlier, my guess would be that r2 comes out negative, so
you could test for that. It's also conceivable that one of the deltas
got set to a NaN somehow, depending on what initializeDeltaXYZ does.

JosephKK

unread,
Jun 6, 2009, 5:51:24 PM6/6/09
to
On Thu, 04 Jun 2009 19:30:04 -0700, Keith Thompson <ks...@mib.org>
wrote:

>Olumide <50...@web.de> writes:
>> I recently had a colleague introduce me to the variable macro
>> DBL_EPSILON and the function _isnan(), because some of my functions
>> return 1.#QNANO values. However, I'm not sure of of how best to use
>> DBL_EPSILON and _isnan(). Which is the better way to test for a small
>> double:
>>
>> Method 1: _isnan( really_small_double );
>>
>> Method 2: if( really_small_double < DBL_EPSILON ) // do stuff
>
>Neither.
>
>C99 has a standard macro isnan(); if your implementation doesn't
>support it, it might instead have something similar called "_isnan()".
>You'll have to consult your implementation's documentation to find out
>exactly what it does. But it almost certainly tests whether its
>argument is a NaN -- which stands for "Not a Number". It's not a
>really small number; it's not a number at all.
>
>DBL_EPSILON is the difference between 1.0 and the next representable
>number above 1.0.

Not really. It specifies the guaranteed accuracy of mathematical
operations, not the resolution. The difference can be pretty subtle,
but consider: if you are dealing with largish quantities, say
Avogadro's number, and you want to know the number of atoms delta
resolution that can be represented it would still be many trillions.
But the accuracy ratio scales directly with the size of the numbers
represented, and this is but one of the contributing components to a
property called numerical instability.

JosephKK

unread,
Jun 6, 2009, 6:14:18 PM6/6/09
to
On Sat, 6 Jun 2009 01:14:11 GMT, "Dik T. Winter" <Dik.W...@cwi.nl>
wrote:

>In article <c9c6b947-5a46-4b86...@g20g2000vba.googlegroups.com> Olumide <50...@web.de> writes:
>...
> > Perhaps then the problem is a NaN. My functions perform lots of
> > computation of the type: a^b, and occasionally, a is a very small
> > number, while b is negative, so that the result tends to 1/0 . Might
> > this explain why my function occasionally returns 1.#QNANO?
>
>No, that would result in an infinity, not in a NAN. The only way that could
>yield a NAN would be if a was negative (and with a well-designed library,
>b non-integral). In all other cases a number or an infinity should be
>returned (with the now common IEEE standard arithmetic).
>
>So I suspect your a has become negative.

As much as i don't like to argue with you i expect a NaN and an
overflow indication (which may be going unhandled). But then i am
coming from the hardware side.

Martin Eisenberg

unread,
Jun 6, 2009, 6:28:59 PM6/6/09
to
JosephKK wrote:
> On Thu, 04 Jun 2009 19:30:04 -0700, Keith Thompson
> <ks...@mib.org> wrote:

>>DBL_EPSILON is the difference between 1.0 and the next
>>representable number above 1.0.
>
> Not really. It specifies the guaranteed accuracy of
> mathematical operations, not the resolution.

Yes it does. C++98 final draft, 18.2.1.2/20 says:

| static T epsilon() throw();
|
| Machine epsilon: the difference between 1 and the least value
| greater than 1 that is representable. 8)
|
| 8) Equivalent to FLT_EPSILON, DBL_EPSILON, LDBL_EPSILON.

The C++ standard does not define accuracy, but IEEE754 mandates that
the relative error of basic operations not exceed 1 ulp which roughly
means the interval [-2*epsilon, epsilon].


Martin

--
Quidquid latine scriptum est, altum videtur.

JosephKK

unread,
Jun 6, 2009, 6:31:06 PM6/6/09
to
On Sat, 06 Jun 2009 10:33:26 -0700, Nate Eldredge <na...@vulcan.lan>
wrote:

I do not see any way for r2 to ever come out negative, deltaX is a
different matter.

Martin Eisenberg

unread,
Jun 6, 2009, 6:42:28 PM6/6/09
to
Martin Eisenberg wrote:

> The C++ standard does not define accuracy, but IEEE754 mandates
> that the relative error of basic operations not exceed 1 ulp
> which roughly means the interval [-2*epsilon, epsilon].

Correction: [-1,1]*epsilon.

Nate Eldredge

unread,
Jun 6, 2009, 7:23:33 PM6/6/09
to
"JosephKK"<quiett...@yahoo.com> writes:

On my system (amd64, gcc, FreeBSD), print("%f\n", pow(0.0, -1.0)) prints
"inf".

Nate Eldredge

unread,
Jun 6, 2009, 7:25:10 PM6/6/09
to
"JosephKK"<quiett...@yahoo.com> writes:

> I do not see any way for r2 to ever come out negative, deltaX is a
> different matter.

Oops, I didn't read it carefully. r2 is a sum of squares.

James Kuyper

unread,
Jun 6, 2009, 7:32:32 PM6/6/09
to
JosephKK wrote:
> On Thu, 04 Jun 2009 19:30:04 -0700, Keith Thompson <ks...@mib.org>
> wrote:
...

>> DBL_EPSILON is the difference between 1.0 and the next representable
>> number above 1.0.
>
> Not really. ...

Yes, really. The C standard defines it as: "the difference between 1 and
the least value greater than 1 that is representable in the given
floating point type ..." (5.2.4.2.2p11). Since this is cross-posted to
C++, I'll also mention that the C++ standard incorporates the C standard
library by reference (1.2p2) and specifically mentions both <float.h>
(D.5p1) and DBL_EPSILON (C.2p4) as features of that library which are so
incorporated, and specifies that for <cfloat> ”The contents are the
same as the Standard C library header <float.h>”. (18.2.2p4).

> ... It specifies the guaranteed accuracy of mathematical
> operations, not the resolution The difference can be pretty subtle,


> but consider: if you are dealing with largish quantities, say
> Avogadro's number, and you want to know the number of atoms delta
> resolution that can be represented it would still be many trillions.
> But the accuracy ratio scales directly with the size of the numbers
> represented, and this is but one of the contributing components to a
> property called numerical instability.

The definition of DBL_EPSILON is cited above. It's quite simple, and
makes no mention of any of those issues. Those issues are certainly
related to it, but not in any way that justifies saying "Not really.".

Joe Wright

unread,
Jun 6, 2009, 7:38:03 PM6/6/09
to

Yes really. The definition of EPSILON is in simple English:

the difference between 1 and the least value greater
than 1 that is representable in the given floating

point type, b^1-p.

In the case of float that is 2^-23. Consider:

00110100 00000000 00000000 00000000
Exp = 104 (-22)
11101010
Man = .10000000 00000000 00000000
1.19209290e-07

This is the representation of FLT_EPSILON. Adding 1 to it:

00111111 10000000 00000000 00000001
Exp = 127 (1)
00000001
Man = .10000000 00000000 00000001
1.00000012e+00

Consider the mantissa (significand?). The bit at b23 is the 1 and the
bit at b0 is EPSILON. It shows us graphically the limits of precision
and accuracy of a float. The term (1.0 + FLT_EPSILON) is useful in
determining the granularity of a given floating point value.

--
Joe Wright
"Memory is the second thing to go. I forget what the first is."

James Kuyper

unread,
Jun 6, 2009, 7:50:58 PM6/6/09
to
James Kuyper wrote:

> incorporated, and specifies that for <cfloat> †The contents are the
> same as the Standard C library header <float.h>†. (18.2.2p4).

Sorry about that - but I've finally figured out what's going wrong. My
computer has software installed that lets me easily insert characters in
encodings and fonts designed for showing both Chinese and English text.d
It switches modes automatically when I hit Shift-Space, or Ctrl-Space,
key combinations that I've been hitting by accident far too frequently
lately.

That was supposed to say:

> incorporated, and specifies that for <cfloat.h> "The contents are the

Eric Sosman

unread,
Jun 6, 2009, 10:10:55 PM6/6/09
to
JosephKK wrote:
> On Thu, 04 Jun 2009 19:30:04 -0700, Keith Thompson <ks...@mib.org>
> wrote:
>>
>> DBL_EPSILON is the difference between 1.0 and the next representable
>> number above 1.0.
>
> Not really.

Yes, really. In comp.lang.c at any rate; comp.lang.c++
is beyond my knowledge or speculation. 5.2.4.2.2p10 *defines*
DBL_EPSILON as

"the difference between 1 and the least value greater

than 1 that is representable in [double]"

... and goes on to say that it shall not exceed 1E-9.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Richard Bos

unread,
Jun 7, 2009, 5:04:00 AM6/7/09
to
Nate Eldredge <na...@vulcan.lan> wrote:

> Olumide <50...@web.de> writes:
>
> > Okay, here is a snip of a typical section of code that occasionally
> > results in a output being 1.#QNANO:
> >
> > double deltaX, deltaY, deltaZ;
> > initializeDeltaXYZ( ... );
> > double r2 = deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
> > double output = 2 * m_alpha * pow( r2 , m_alpha - 1 ) + 4 * m_alpha *
> > (m_alpha - 1) * pow( deltaX , 2 ) * pow( r2 , m_alpha - 2 );
>
> I'd suggest printing the values of all these variables (r2, m_alpha, and
> all the deltas) before the computation of `output'. That will probably
> bring enlightenment.

I agree.

> > What I would like to know is:
> >
> > 1. why output is sometimes evaluated as 1.#QNANO in this case
> >
> > 2. how to test when this happens.
>
> As mentioned earlier, my guess would be that r2 comes out negative,

That seems unlikely; floating point inaccuracies are one thing, but
changing the sign of a sum of (non-complex) squares to negative is
another game.

> so you could test for that. It's also conceivable that one of the deltas
> got set to a NaN somehow, depending on what initializeDeltaXYZ does.

Sounds more likely to me. Or that m_alpha is.

Richard

pete

unread,
Jun 7, 2009, 7:03:55 AM6/7/09
to
Keith Thompson wrote:

> Oh, and (x < DBL_EPSILON) is true for very large negative numbers.

Isn't it true for *all* negative numbers?

--
pete

Keith Thompson

unread,
Jun 7, 2009, 11:11:23 AM6/7/09
to

Of course (and for 0.0), but the intended point of the comparison was
to determine whether x is "really small".

JosephKK

unread,
Jun 8, 2009, 1:31:22 AM6/8/09
to

I was talking in clc, was not mindful of crossposting. Besides being
more of a hardware type i care more about IEEE-754 terminology.
j

JosephKK

unread,
Jun 8, 2009, 1:38:28 AM6/8/09
to
On Sat, 06 Jun 2009 23:50:58 GMT, James Kuyper
<james...@verizon.net> wrote:

>James Kuyper wrote:
>
>> incorporated, and specifies that for <cfloat> �The contents are the
>> same as the Standard C library header <float.h>�. (18.2.2p4).


>
>Sorry about that - but I've finally figured out what's going wrong. My
>computer has software installed that lets me easily insert characters in
>encodings and fonts designed for showing both Chinese and English text.d
>It switches modes automatically when I hit Shift-Space, or Ctrl-Space,
>key combinations that I've been hitting by accident far too frequently
>lately.
>
>That was supposed to say:
>
> > incorporated, and specifies that for <cfloat.h> "The contents are the
> > same as the Standard C library header <float.h>" (18.2.2p4).

Well shit. The standards say what the standards say. I am corrected
on what they say. It does not alter the real properties of the real
hardware, nor the mathematical properties thereof. Overextend your
trust in the programming language standards at your own risk.

JosephKK

unread,
Jun 8, 2009, 2:05:30 AM6/8/09
to
On Sat, 06 Jun 2009 16:25:10 -0700, Nate Eldredge <na...@vulcan.lan>
wrote:

>"JosephKK"<quiett...@yahoo.com> writes:

Just the same i can't figure out the issue or the underlying problem
well enough to help OP much. I wonder if OP is trying to "white room"
a well known mathematical algorithm.
?

JosephKK

unread,
Jun 8, 2009, 2:12:46 AM6/8/09
to
On Sat, 06 Jun 2009 16:23:33 -0700, Nate Eldredge <na...@vulcan.lan>
wrote:

>"JosephKK"<quiett...@yahoo.com> writes:

Expected for that particular value pair. What does it get for
pow(-1e-7, -1.5)? OP may be getting this pair or not.
?

Dik T. Winter

unread,
Jun 8, 2009, 6:19:57 AM6/8/09
to
In article <dkol25ted7lh52pq0...@4ax.com> "JosephKK"<quiett...@yahoo.com> writes:
> On Thu, 04 Jun 2009 19:30:04 -0700, Keith Thompson <ks...@mib.org>
> wrote:
...

> >DBL_EPSILON is the difference between 1.0 and the next representable
> >number above 1.0. =20

>
> Not really. It specifies the guaranteed accuracy of mathematical
> operations, not the resolution.

It would be better if you read the standard before pronouncing things like
this.

James Kuyper

unread,
Jun 8, 2009, 7:00:51 AM6/8/09
to
JosephKK wrote:
...

> Well shit. The standards say what the standards say. I am corrected
> on what they say. It does not alter the real properties of the real
> hardware, nor the mathematical properties thereof. ...

DBL_EPSILON Is not a mathematical abstraction, it is a macro defined in
the C standard library, with a value whose meaning is specified by the C
standard.

When you wrote "Not really.", you were objecting to a true statement
about DBL_EPSILON, not a statement about "the real properties of real
hardware".

When you wrote the sentence which starts "It specifies ...", the subject
of that sentence was "It", which in context had to be a reference to the
use of DBL_EPSILON in the message you were responding to. Again, what
you said about "it" may have been true with regard to some entity
related to "the real properties of real hardware", but you didn't
identify which entity that is; it certainly is not DBL_EPSILON.

> ... Overextend your


> trust in the programming language standards at your own risk.

I trust DBL_EPSILON to be the difference between 1.0 and the next number
after 1.0 that is representable as a double. Combining that fact with
the definition of C's floating point model given in 5.2.4.2.2p1-2, and
the value of FLT_RADIX, I can calculate the spacing between x and the
next representable number for any value of x that satisfies (DBL_MIN <=
x && x < DBL_MAX) || (-DBL_MAX <= x && x < -DBL_MIN).

Thinking that DBL_EPSILON means anything other than that would be
"overextending" the definition (as CBFalconer so spectacularly
demonstrated in a recent thread), but that's not because of trusting the
programming language standards too much, but because of misunderstanding
what they say.

James Kuyper

unread,
Jun 8, 2009, 7:05:14 AM6/8/09
to

As DIk said "... if a was negative ...". So do you now agree with what
he said? Would you still expect "a NaN and an overflow indication" even
when a is not negative?

JosephKK

unread,
Jun 8, 2009, 10:10:17 PM6/8/09
to

The C standard says what it says. It defines a few thing in certain
ways. Those definitions are often somewhat at odds with how the
hardware operates and the way that IEEE-754 specifies that they
operate. Thus when the hardware acts differently than what the C
standard specifies, it is not the hardware that is defective.
;
Never mind we are talking past each other.

JosephKK

unread,
Jun 8, 2009, 10:15:52 PM6/8/09
to
On Mon, 8 Jun 2009 10:19:57 GMT, "Dik T. Winter" <Dik.W...@cwi.nl>
wrote:

>In article <dkol25ted7lh52pq0...@4ax.com> "JosephKK"<quiett...@yahoo.com> writes:


> > On Thu, 04 Jun 2009 19:30:04 -0700, Keith Thompson <ks...@mib.org>
> > wrote:
>...
> > >DBL_EPSILON is the difference between 1.0 and the next representable
> > >number above 1.0. =20
> >
> > Not really. It specifies the guaranteed accuracy of mathematical
> > operations, not the resolution.
>
>It would be better if you read the standard before pronouncing things like
>this.

Well fudge. The standard defines it the way that it does. That
definition is in conflict with the way the IEEE-745 compliant hardware
operates. And i am a hardware type.

JosephKK

unread,
Jun 8, 2009, 10:21:19 PM6/8/09
to

Some 25 years ago i studied the IEEE-754 specification pretty
thoroughly, it left me with a deep sense of how the hardware would
operate. This came after deep understanding of two other
implementations all the way down to the gate level.

James Kuyper

unread,
Jun 8, 2009, 10:49:49 PM6/8/09
to
JosephKK wrote:
...

> The C standard says what it says. It defines a few thing in certain
> ways. Those definitions are often somewhat at odds with how the
> hardware operates and the way that IEEE-754 specifies that they
> operate. Thus when the hardware acts differently than what the C
> standard specifies, it is not the hardware that is defective.
> ;
> Never mind we are talking past each other.

I'd prefer not to be talking past each other. I'm aware that there are
inconsistencies of the kind you mention in some other parts of the
standard; in particular, I've heard that some of the specifications in
Annex F about how signed zeros and signed infinities are supposed to be
handled don't jibe with the IEEE-754.

But is there anything that the standard says about DBL_EPSILON
specifically which is "somewhat at odds with the hardware operates and
the way that IEEE-754 specifies that they operate"? If so, how? I'm at a
loss to imagine how it could be. As far as I know, all floating point
representations have a unique next-representable value after 1.0, and
that would seem to be the only requirement for the definition of
DBL_EPSILON to be meaningful.

James Kuyper

unread,
Jun 8, 2009, 10:52:46 PM6/8/09
to
JosephKK wrote:
> On Mon, 08 Jun 2009 11:05:14 GMT, James Kuyper
> <james...@verizon.net> wrote:
...

>> As DIk said "... if a was negative ...". So do you now agree with what
>> he said? Would you still expect "a NaN and an overflow indication" even
>> when a is not negative?
>
> Some 25 years ago i studied the IEEE-754 specification pretty
> thoroughly, it left me with a deep sense of how the hardware would
> operate. This came after deep understanding of two other
> implementations all the way down to the gate level.

I asked a question with a yes or no answer; I can't translate what
you've said into either "yes" or "no", nor can I translate it into
anything resembling a claim that the restriction to "yes" and "no" is
inappropriate.

In other words, I don't see how your response can be interpreted as an
answer to my question.

Keith Thompson

unread,
Jun 9, 2009, 2:37:46 AM6/9/09
to

How so? The definition of DBL_EPSILON isn't about the way the
hardware operates; it's an unambiguous definition of a number. Just
what conflict do you see?

Richard Herring

unread,
Jun 9, 2009, 6:08:19 AM6/9/09
to
In message <36hr25179ntpbso5m...@4ax.com>, JosephKK
<quiett...@yahoo.com> writes

>On Mon, 8 Jun 2009 10:19:57 GMT, "Dik T. Winter" <Dik.W...@cwi.nl>
>wrote:
>
>>In article <dkol25ted7lh52pq0...@4ax.com>
>>"JosephKK"<quiett...@yahoo.com> writes:
>> > On Thu, 04 Jun 2009 19:30:04 -0700, Keith Thompson <ks...@mib.org>
>> > wrote:
>>...
>> > >DBL_EPSILON is the difference between 1.0 and the next representable
>> > >number above 1.0. =20
>> >
>> > Not really. It specifies the guaranteed accuracy of mathematical
>> > operations, not the resolution.
>>
>>It would be better if you read the standard before pronouncing things like
>>this.
>
>Well fudge.

"When in hole, stop digging".

>The standard defines it the way that it does. That
>definition is in conflict with the way the IEEE-745 compliant hardware
>operates.

Since the definition is entirely in terms of how the hardware operates
("next representable number above 1.0"), how can that be?

>And i am a hardware type.

I see. And I always thought hardware was based on logic.

--
Richard Herring

Dik T. Winter

unread,
Jun 9, 2009, 8:42:56 AM6/9/09
to
In article <qlgr25dp28kh374on...@4ax.com> "JosephKK"<quiett...@yahoo.com> writes:
...

> The C standard says what it says. It defines a few thing in certain
> ways. Those definitions are often somewhat at odds with how the
> hardware operates and the way that IEEE-754 specifies that they
> operate.

In what way is the hardware operation different from the C standard definition
of DBL_EPSILON? Or do you state that in hardware DBL_EPSILON (that is the
difference between 1.0 and the next higher number) is not equal to the
difference between 1.0 and the next higher number? Why not?

Dik T. Winter

unread,
Jun 9, 2009, 8:44:39 AM6/9/09
to
In article <36hr25179ntpbso5m...@4ax.com> "JosephKK"<quiett...@yahoo.com> writes:
> On Mon, 8 Jun 2009 10:19:57 GMT, "Dik T. Winter" <Dik.W...@cwi.nl>
> wrote:
...
> > > >DBL_EPSILON is the difference between 1.0 and the next representable
> > > >number above 1.0.
> > >
> > > Not really. It specifies the guaranteed accuracy of mathematical
> > > operations, not the resolution.
> >
> > It would be better if you read the standard before pronouncing things
> > like this.
>
> Well fudge. The standard defines it the way that it does. That
> definition is in conflict with the way the IEEE-745 compliant hardware
> operates. And i am a hardware type.

In what way does it conflict with how the hardware operates? I have no
idea about what you do mean here. DBL_EPSILON is defined in a certain,
precise, way. I do not see how the hardware comes into it.

JosephKK

unread,
Jun 10, 2009, 12:36:22 AM6/10/09
to
On Tue, 9 Jun 2009 12:44:39 GMT, "Dik T. Winter" <Dik.W...@cwi.nl>
wrote:

>In article <36hr25179ntpbso5m...@4ax.com> "JosephKK"<quiett...@yahoo.com> writes:
> > On Mon, 8 Jun 2009 10:19:57 GMT, "Dik T. Winter" <Dik.W...@cwi.nl>
> > wrote:
>...
> > > > >DBL_EPSILON is the difference between 1.0 and the next representable
> > > > >number above 1.0.
> > > >
> > > > Not really. It specifies the guaranteed accuracy of mathematical
> > > > operations, not the resolution.
> > >
> > > It would be better if you read the standard before pronouncing things
> > > like this.
> >
> > Well fudge. The standard defines it the way that it does. That
> > definition is in conflict with the way the IEEE-745 compliant hardware
> > operates. And i am a hardware type.
>
>In what way does it conflict with how the hardware operates? I have no
>idea about what you do mean here. DBL_EPSILON is defined in a certain,
>precise, way. I do not see how the hardware comes into it.

I did a study of compliance of 8087 versus the Cyrix and Weitek knock
offs about 25 years ago. The standard has not changed much since. If
you really, really want to know get a copy and study it.

Example: with 53 bits of mantissa, DBL_EPSILON would be closer to
1E-19 rather than 1E-9

JosephKK

unread,
Jun 10, 2009, 12:47:31 AM6/10/09
to
On Tue, 09 Jun 2009 02:52:46 GMT, James Kuyper
<james...@verizon.net> wrote:

Please read it as my background tells me what to expect, based on the
described values. If that conflicts with what you expect, please test
it and tell us all what happened; oops that would require assembler
programming instead of "C". Then again you may be well able to
develop those programs anyway. It is up to you to do what please.

user923005

unread,
Jun 10, 2009, 2:39:18 AM6/10/09
to
On Jun 9, 9:36 pm, "JosephKK"<quiettechb...@yahoo.com> wrote:
> On Tue, 9 Jun 2009 12:44:39 GMT, "Dik T. Winter" <Dik.Win...@cwi.nl>
> wrote:
>
> >In article <36hr25179ntpbso5mml24vt96a8q953...@4ax.com> "JosephKK"<quiettechb...@yahoo.com> writes:
> > > On Mon, 8 Jun 2009 10:19:57 GMT, "Dik T. Winter" <Dik.Win...@cwi.nl>

> > > wrote:
> >...
> > > > > >DBL_EPSILON is the difference between 1.0 and the next representable
> > > > > >number above 1.0.
>
> > > > > Not really.  It specifies the guaranteed accuracy of mathematical
> > > > > operations, not the resolution.
>
> > > > It would be better if you read the standard before pronouncing things
> > > > like this.
>
> > > Well fudge.  The standard defines it the way that it does.  That
> > > definition is in conflict with the way the IEEE-745 compliant hardware
> > > operates.  And i am a hardware type.
>
> >In what way does it conflict with how the hardware operates?  I have no
> >idea about what you do mean here.  DBL_EPSILON is defined in a certain,
> >precise, way.  I do not see how the hardware comes into it.
>
> I did a study of compliance of 8087 versus the Cyrix and Weitek knock
> offs about 25 years ago.  The standard has not changed much since.  If
> you really, really want to know get a copy and study it.

Telling Dik Winter to study an applied math paper is like telling
George Marsaglia to read you paper on PRNGs or Donald Knuth to read
your article about the art of computer programming.

> Example: with 53 bits of mantissa, DBL_EPSILON would be closer to
> 1E-19 rather than 1E-9

I would say that 1E-19 is off by about a factor of ~ 2220 unless you
know something I don't know.
{My calculation would be: eps is 2.0/pow(2.0,53.0) for a 53 bit
mantissa.}

Flash Gordon

unread,
Jun 10, 2009, 2:38:14 AM6/10/09
to

So? The C standard says that if the correct value of DBL_EPSILON is
1E-19 then that is what the implementation has to define it as. The
specific value mentioned in the standard is a limit on what it is
allowed to be, not the specific value to be used in every implementation.

To be clear, if the difference between 1.0 and the next representable
number in the floating point format used by the hardware is 1E-19, then
the C standard *requires* that DBL_EPSILON be defined as 1E-19 (this
specific exact value would require base 10 floating point rather than
base 2, which is allowed by the standard).

The C++ standard is, I believe, the same in this respect.
--
Flash Gordon

James Kuyper

unread,
Jun 10, 2009, 6:23:04 AM6/10/09
to
JosephKK wrote:
> On Tue, 09 Jun 2009 02:52:46 GMT, James Kuyper
> <james...@verizon.net> wrote:
>
>> JosephKK wrote:
>>> On Mon, 08 Jun 2009 11:05:14 GMT, James Kuyper
>>> <james...@verizon.net> wrote:
>> ...
>>>> As DIk said "... if a was negative ...". So do you now agree with what
>>>> he said? Would you still expect "a NaN and an overflow indication" even
>>>> when a is not negative?
>>> Some 25 years ago i studied the IEEE-754 specification pretty
>>> thoroughly, it left me with a deep sense of how the hardware would
>>> operate. This came after deep understanding of two other
>>> implementations all the way down to the gate level.
...

>> In other words, I don't see how your response can be interpreted as an
>> answer to my question.
>
> Please read it as my background tells me what to expect, based on the
> described values. If that conflicts with what you expect, please test
> it and tell us all what happened; oops that would require assembler
> programming instead of "C". Then again you may be well able to
> develop those programs anyway. It is up to you to do what please.

My question was about what your expectations were; I can't get the
answer to that question by writing a test program; not unless that test
program is hooked up to mind-reading hardware.

Also, this was a question about the behavior of C code, not about
assembler code, so what point would there be to writing assembler code
to determine the answer?

If the floating point hardware implements a near-equivalent of the
pow(a,n) function, that differs from the specification of pow() by
returning a NaN and an overflow indicator when a is a small positive
number, and b is a sufficiently large negative number, then the
implementation of the pow() function is required to contain whatever
additional code is needed to ensure that the behavior of the pow()
function itself meets the requirements of 7.12.1p4:

"If a floating result overflows and default rounding is in effect, or if
the mathematical result is an exact infinity from finite arguments (for
example log(0.0)), then the function returns the value of the macro
HUGE_VAL,HUGE_VALF, or HUGE_VALL according to the return type, with the
same sign as the correct value of the function; if the integer
expression math_errhandling & MATH_ERRNO is nonzero, the integer
expression errno acquires the value ERANGE; if the integer expression
math_errhandling & MATH_ERREXCEPT is nonzero, the ‘‘divide-by-zero’’
floating-point exception is raised if the mathematical result is an
exact infinity and the ‘‘overflow’’ floating-point exception is raised
otherwise."

Note: I'm pretty sure that the parts involving math_errhandling are new
to C99; I'm not sure what the corresponding wording in the C90 standard was.

The required return value in this case, HUGE_VAL, must be positive
(7.12p3), and therefore cannot be a NaN, and must (if __STDC_IEC_559__
is predefined) be positive infinity (F9p1).

There's nothing particularly unusual about a discrepancy between the
behavior of the floating point hardware and the behavior of the
corresponding standard library function. That's precisely the point of
standardizing the library, so people can write code that relies upon the
standard's guarantees, without having to worry about the details of
different hardware implementations.

Dik T. Winter

unread,
Jun 10, 2009, 6:29:44 AM6/10/09
to
In article <qldu251rgdo3rkl8s...@4ax.com> "JosephKK"<quiett...@yahoo.com> writes:
> On Tue, 9 Jun 2009 12:44:39 GMT, "Dik T. Winter" <Dik.W...@cwi.nl>
> wrote:
...

> >In what way does it conflict with how the hardware operates? I have no
> >idea about what you do mean here. DBL_EPSILON is defined in a certain,
> >precise, way. I do not see how the hardware comes into it.
>
> I did a study of compliance of 8087 versus the Cyrix and Weitek knock
> offs about 25 years ago. The standard has not changed much since.

The standard has not changed at all, but the 8087 (and 80187) is not standard
compliant (it was based on a preliminary version of it). As far as I know,
Cyrix and Weitek were standard compliant. Yhe 80287 was the first standard
compliant Intel FP processor.

> If
> you really, really want to know get a copy and study it.

Do you think I do not know that standard?

> Example: with 53 bits of mantissa, DBL_EPSILON would be closer to
> 1E-19 rather than 1E-9

Where is written that DBL_EPSILON is something like 1E-9? With IEEE,
DBL_EPSILON equals 2^(-52).

JosephKK

unread,
Jun 10, 2009, 10:07:19 PM6/10/09
to
On Wed, 10 Jun 2009 10:29:44 GMT, "Dik T. Winter" <Dik.W...@cwi.nl>
wrote:

>In article <qldu251rgdo3rkl8s...@4ax.com> "JosephKK"<quiett...@yahoo.com> writes:
> > On Tue, 9 Jun 2009 12:44:39 GMT, "Dik T. Winter" <Dik.W...@cwi.nl>
> > wrote:
>...
> > >In what way does it conflict with how the hardware operates? I have no
> > >idea about what you do mean here. DBL_EPSILON is defined in a certain,
> > >precise, way. I do not see how the hardware comes into it.
> >
> > I did a study of compliance of 8087 versus the Cyrix and Weitek knock
> > offs about 25 years ago. The standard has not changed much since.
>
>The standard has not changed at all, but the 8087 (and 80187) is not standard
>compliant (it was based on a preliminary version of it).

True that the 8087 was not quite compliant. However the Cyrix
mimicked those errors, but not the Weitek.

>As far as I know,
>Cyrix and Weitek were standard compliant. Yhe 80287 was the first standard
>compliant Intel FP processor.

Somewhere somebody said that storing the X87 80 bit temporary values
required a conversion that was time costly, it was not. Moreover you
could store the 80-bit register contents as well. This as also true
for the 68881 series FPU as well.


>
> > If
> > you really, really want to know get a copy and study it.
>
>Do you think I do not know that standard?

I would not be surprised if you had studied it recently.

I checked its current form dated 2008 and they incorporated decimal
floating point from IEEE-854. Among other things this made many more
software implementations compliant and the hardware of IBM s/390
compliant.


>
> > Example: with 53 bits of mantissa, DBL_EPSILON would be closer to
> > 1E-19 rather than 1E-9

Ah yes, the implementation value may be different from the "C"
standard limit value. Sloppy on my part.

JosephKK

unread,
Jun 10, 2009, 10:14:34 PM6/10/09
to
On Wed, 10 Jun 2009 10:23:04 GMT, James Kuyper
<james...@verizon.net> wrote:

It is still embedded in the quoted text above. "a NaN and an
overflow indication"
>

James Kuyper

unread,
Jun 11, 2009, 5:44:58 AM6/11/09
to
JosephKK wrote:
> On Wed, 10 Jun 2009 10:23:04 GMT, James Kuyper
> <james...@verizon.net> wrote:
>
>> JosephKK wrote:
>>> On Tue, 09 Jun 2009 02:52:46 GMT, James Kuyper
>>> <james...@verizon.net> wrote:
>>>
>>>> JosephKK wrote:
>>>>> On Mon, 08 Jun 2009 11:05:14 GMT, James Kuyper
>>>>> <james...@verizon.net> wrote:
>>>> ...
>>>>>> As DIk said "... if a was negative ...". So do you now agree with what
>>>>>> he said? Would you still expect "a NaN and an overflow indication" even
>>>>>> when a is not negative?
...

>> My question was about what your expectations were; I can't get the
>> answer to that question by writing a test program; not unless that test
>> program is hooked up to mind-reading hardware.
>
> It is still embedded in the quoted text above. "a NaN and an
> overflow indication"

Since that phrase occurs in the quoted material, only as part of a
question about whether you still expected those results, an actual
answer was in fact requested; an actual answer to my question could not
be inferred from anything you've previously said in response to. I was
expecting that you were addressing the more general case, where a could
be negative, and not the actual case being discussed, where a is
actually positive.

OK, so the fact that 'a' is positive, and that pow(a,n) is therefore not
allowed to return a NaN, has not had any impact on your expectations for
the behavior of pow(a,n). Odd. Not a good way to think while writing C
or C++ code - but to each his own.

James Kuyper

unread,
Jun 11, 2009, 6:15:53 AM6/11/09
to
JosephKK wrote:
> On Wed, 10 Jun 2009 10:29:44 GMT, "Dik T. Winter" <Dik.W...@cwi.nl>
> wrote:
>
>> In article <qldu251rgdo3rkl8s...@4ax.com> "JosephKK"<quiett...@yahoo.com> writes:
...

>>> Example: with 53 bits of mantissa, DBL_EPSILON would be closer to
>>> 1E-19 rather than 1E-9
>
> Ah yes, the implementation value may be different from the "C"
> standard limit value. Sloppy on my part.

Replace "may be different from" with "must be <=", and you more
accurately express the meaning of the standard value.

Dik T. Winter

unread,
Jun 11, 2009, 8:16:21 AM6/11/09
to
In article <hlo035tsos55ehn4j...@4ax.com> "JosephKK"<quiett...@yahoo.com> writes:
> On Wed, 10 Jun 2009 10:29:44 GMT, "Dik T. Winter" <Dik.W...@cwi.nl>
> wrote:
...
> > > >In what way does it conflict with how the hardware operates? I have
> > > >no idea about what you do mean here. DBL_EPSILON is defined in a
> > > >certain, precise, way. I do not see how the hardware comes into it.
> > >
> > > I did a study of compliance of 8087 versus the Cyrix and Weitek knock
> > > offs about 25 years ago. The standard has not changed much since.
> >
> >The standard has not changed at all, but the 8087 (and 80187) is not
> >standard compliant (it was based on a preliminary version of it).
>
> True that the 8087 was not quite compliant.

Yes, Intel wanted the chip design to be complete, although the standard was
not yet finalized. So the 8087 did have only one infinity.

> > The 80287 was the first


> >standard compliant Intel FP processor.
>
> Somewhere somebody said that storing the X87 80 bit temporary values
> required a conversion that was time costly, it was not. Moreover you
> could store the 80-bit register contents as well. This as also true
> for the 68881 series FPU as well.

What is the relevance?

> > > If
> > > you really, really want to know get a copy and study it.
> >
> >Do you think I do not know that standard?
>
> I would not be surprised if you had studied it recently.

Well, I have not. The last time I really studied it was some 20 years ago.

> > > Example: with 53 bits of mantissa, DBL_EPSILON would be closer to
> > > 1E-19 rather than 1E-9
> >

> >Where is written that DBL_EPSILON is something like 1E-9? With IEEE,
> >DBL_EPSILON equals 2^(-52).
>
> Ah yes, the implementation value may be different from the "C"
> standard limit value. Sloppy on my part.

Rather, on most implementations the implementation value *must* be different
from the "C" standard limit value. So in IEEE DBL_EPSILON *must* be 2^(-52).

I do not think there are implementations of C around that get it wrong.
Although I know it is sometimes hard for compiler writers to get such things
right. When Ada compilers started arriving I wrote a program that verified
all floating-point attributes that the language defined. This program was
distributed widely and to my surprise, there was *no* implementation that had
everything correct. Even on our Data General MV4000 the compiler said that
the machine-radix was 2 while it actually was 16.

James Kuyper

unread,
Jun 12, 2009, 7:04:56 AM6/12/09
to
JosephKK wrote:

> On Sat, 6 Jun 2009 01:14:11 GMT, "Dik T. Winter" <Dik.W...@cwi.nl>
> wrote:
>
>> In article <c9c6b947-5a46-4b86...@g20g2000vba.googlegroups.com> Olumide <50...@web.de> writes:
>> ...
>>> Perhaps then the problem is a NaN. My functions perform lots of
>>> computation of the type: a^b, and occasionally, a is a very small
>>> number, while b is negative, so that the result tends to 1/0 . Might
>>> this explain why my function occasionally returns 1.#QNANO?
>> No, that would result in an infinity, not in a NAN. The only way that could
>> yield a NAN would be if a was negative (and with a well-designed library,
>> b non-integral). In all other cases a number or an infinity should be
>> returned (with the now common IEEE standard arithmetic).
>>
>> So I suspect your a has become negative.
>
> As much as i don't like to argue with you i expect a NaN and an
> overflow indication (which may be going unhandled). But then i am
> coming from the hardware side.

In a much more recent message, you explained your response as follows:

> Should you carefully read it all again there was at least one
> pow(deltaX,n) involved and delta x could have been negative. It is a
> separate issue from the computation of r2.

The above comments by Olumide and Dik were about a^b, where a is
placeholder representing an arbitrary expression with a small positive
value. You're disagreeing with an assertion that generation of a NaN
implies that 'a has become negative'. How does the possibility that
deltaX might be negative justify disagreeing with that assertion? If you
were agreeing with him, I would not have expected to see words like "I
don't like to argue with you"; instead, I would have expected something
more like

> You're right - in particular, I suspect that deltaX might be negative,
> in which case I would expect to see a NaN and an overflow indication

0 new messages