Where is the similar of FLT_EPSILON / DBL_EPSILON in go

670 views
Skip to first unread message

Sanbo Qin

unread,
Jul 26, 2010, 4:29:34 PM7/26/10
to golang-nuts
I can't find it. I think it is a very useful constant in float
comparison, which is defined in <float.h> in C.
I find some relative constant, such as MaxFloat32, MaxFloat64, MaxInt8
in pkg/math/const.go. But I can't find EPSILON that defined the
smallest number x such that 1.0 + x != 1.0.
Is it good to add it into the go? How about to add it into pkg/math/const.go?
Or if I just miss it, where is it?
Thanks.
Sanbo

Russ Cox

unread,
Jul 26, 2010, 6:38:07 PM7/26/10
to Sanbo Qin, golang-nuts
On Mon, Jul 26, 2010 at 13:29, Sanbo Qin <qsb...@gmail.com> wrote:
> I can't find it. I think it is a very useful constant in float
> comparison, which is defined in <float.h> in C.

I'm curious: how do you use it?

This comes up often enough that we should do something,
but I'm not sure yet exactly what (hence the question).
I've created an issue to track progress on this.

http://code.google.com/p/go/issues/detail?id=966

Russ

David Roundy

unread,
Jul 26, 2010, 8:22:12 PM7/26/10
to r...@golang.org, Sanbo Qin, golang-nuts
On Mon, Jul 26, 2010 at 6:38 PM, Russ Cox <r...@golang.org> wrote:
> On Mon, Jul 26, 2010 at 13:29, Sanbo Qin <qsb...@gmail.com> wrote:
>> I can't find it. I think it is a very useful constant in float
>> comparison, which is defined in <float.h> in C.
>
> I'm curious: how do you use it?

One use would be:

printf("FD Ratio: %25.16f\n", (Eplus-Eminus)/(2*dx)/deriv);
printf("FD sigfigs: %25.16f\n", EPSILON*fabs(Eold/(Eplus-Eminus)));

although to be honest, I cheated and changed 1e-15 to EPSILON in this
example... which incidentally was from code I was working on just this
morning. It's estimating the fractional roundoff error in a finite
difference derivative calculation, which is being used to test a
gradient computation. So we use this to see whether our error is
likely to be overwhelmed by roundoff error, as a human examination
approach. In this case it isn't particularly important to use
EPSILON, since that's just a lower bound on the error, and we
typically have an order of magnitude or two more error than that.
--
David Roundy

Sanbo Qin

unread,
Jul 26, 2010, 11:48:21 PM7/26/10
to David Roundy, r...@golang.org, golang-nuts
I use FLT_EPSILON / DBL_EPSILON for only one reason, testing floating
point numbers for equality.
base on http://c-faq.com/fp/fpequal.html
Rather than

double a, b;
...
if(a == b) /* WRONG */

use something like

#include <math.h>

if(fabs(a - b) <= epsilon * fabs(a))

Although everybody can make value for his own problem, a build-in
constant is helpful.
http://en.wikipedia.org/wiki/Machine_epsilon

A search on FLT_EPSILON (
http://www.google.com/search?q=FLT_EPSILON+filetype:c ) reveals it is
widely used.

Sanbo

David Roundy

unread,
Jul 27, 2010, 8:21:02 AM7/27/10
to Sanbo Qin, r...@golang.org, golang-nuts
On Mon, Jul 26, 2010 at 11:48 PM, Sanbo Qin <qsb...@gmail.com> wrote:
> I use FLT_EPSILON / DBL_EPSILON  for only one reason, testing floating
> point numbers for equality.
> base on  http://c-faq.com/fp/fpequal.html
> Rather than
>
>        double a, b;
>        ...
>        if(a == b)      /* WRONG */
>
> use something like
>
>        #include <math.h>
>
>        if(fabs(a - b) <= epsilon * fabs(a))

Although this is still wrong in the same sense just a little less so.
It really depends on why you're checking for equality! To quote from
the link you cited:

"The precise value of epsilon may still have to be chosen with care:
its appropriate value may be quite small and related only to the
machine's floating-point precision, or it may be larger if the numbers
being compared are inherently less accurate or are the results of a
chain of calculations which compounds accuracy losses over several
steps. (Also, you may have to make the threshold a function of b, or
of both a and b.)"

The degree of fuzz needed is entirely dependent on how these numbers
are computed and what you're comparing for. Checking for exact
equality is great if you've got a stable iterative algorithm and you
want to iterate to convergence. Or you could do a fuzzy comparison if
you want less precision, but using FLT_EPSILON is probably only
correct in a minority of cases.

David

Reply all
Reply to author
Forward
0 new messages