Re: exp() bug?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Eljay:

Hi.  Thanks for your reply.

Yes, I agree with the situation, but I still am surprised that after
all these years gcc has not produced an option to ensure consistent
results.

Below is an update on my posting to cygwin.com.

Thanks.

Lester

On Tue, Oct 05, 2004 at 11:25:01AM -0500, Eljay Love-Jensen wrote:
: Date: Tue, 05 Oct 2004 11:25:01 -0500
: From: Eljay Love-Jensen <eljay@xxxxxxxxx>
: Subject: Re: exp() bug?
: In-reply-to: <20041005154308.GA3452@xxxxxxxxxx>
: To: Lester Ingber <ingber@xxxxxxxxxx>, gcc-help@xxxxxxxxxxx
: 
: Hi Lester,
: 
: Not a bug.  Different platforms have different hardware, and as such 
: different rounding or algorithms can cause variation in the least 
: significant bits.  (In non-technical terms, the fiddlybits.)
: 
: There are techniques one can use to mitigate those situations.  But they 
: are hard to eliminate.
: 
: Even in Java, which is supposed to be JVM centric and thus platform 
: neutral, suffers from this problem without taking measures to guarantee 
: IEEE 754 compliance.
: 
: Sincerely,
: --Eljay

From: Lester Ingber <ingber@xxxxxxxxxx>
To: cygwin@xxxxxxxxxx
Cc: 
Bcc: 
Subject: Re: exp() bug?
Reply-To: 

The previous email had a typo, in that the OR pairs are as below.
In other words, the conclusion is the same: I saw no differences in
these 4 pairs of runs using or not using -ffloat-store.

In a code I make available to the public, www.ingber.com/ASA.zip, in
order to get consistent results over all reported platforms, I had to
make available a user-defined SMALL_FLOAT to handle most such instances.

Is there another gcc option that can force consistent results?

Lester

      +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=

In reply to:
: From: cygwin-owner On Behalf Of Lester Ingber
: > Sent: 05 October 2004 16:36
: 
: > I believe there is a bug in some gcc's, at least in the exp() function,
: > and at least in the way round-offs are (in)consistently treated.
: 
:   Go on?
: 
: > I first noticed some differences in results in calculations using the
: > MINGW gcc vs the Cygwin gcc on my ThinkPad XPPro machine.  I applied
: > the same code on FreeBsd and on SPARC/Solaris9.
: 
:   First go and google for "What every computer scientist should know about
: floating point", and read the entire paper.  Then try running your tests again,
: but compile them with the "-ffloat-store" option.  Then read "info gcc" about
: -ffloat-store and its effects.
: 
:   Then if you still think there's a bug, come back and describe it.  But if you've
: taken all that in, you no longer will.
: 
:     cheers, 
:       DaveK

I disagree about what the default behavior should be.  In any case, here are
runs with -ffloat-store.  I see no difference.

Lester

      +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
From: Lester Ingber <ingber@xxxxxxxxxx>
To: cygwin@xxxxxxxxxx
Subject: exp() bug?

I believe there is a bug in some gcc's, at least in the exp() function,
and at least in the way round-offs are (in)consistently treated.

I first noticed some differences in results in calculations using the
MINGW gcc vs the Cygwin gcc on my ThinkPad XPPro machine.  I applied
the same code on FreeBsd and on SPARC/Solaris9.

If true, this is a **very** serious bug, leading to very different
answers on pretty standard (complex) calculations, as I discovered.

Here is the code for gcctest.c:
    ------------8<------------ top cut -> bottom ------------->8------------
/*
 * rm gcctest.exe; gcc -O -mno-cygwin -o gcctest.exe gcctest.c -lm; gcctest.exe
 * rm gcctest.exe; gcc -O -o gcctest.exe gcctest.c -lm; gcctest.exe
 *
 * rm gcctest.exe; gcc -O -ffloat-store -mno-cygwin -o gcctest.exe gcctest.c -lm; gcctest.exe
 * rm gcctest.exe; gcc -O -ffloat-store -o gcctest.exe gcctest.c -lm; gcctest.exe
 */

#include <errno.h>
#include <math.h>
#include <stdio.h>

int main ();

int
main ()
{
  double d;

  d = exp (log (1234567.2)) - exp (log (1234567.1));
  printf ("1234567.2-1234567.1: d = %g\n", d);
  d = exp (log (12345678.2)) - exp (log (12345678.1));
  printf ("12345678.2-12345678.1: d = %g\n", d);
  d = exp (log (123456789.2)) - exp (log (123456789.1));
  printf ("123456789.2-123456789.1: d = %g\n", d);
  d = exp (log (1234567891.2)) - exp (log (1234567891.1));
  printf ("1234567891.2-1234567891.1: d = %g\n", d);
  d = exp (log (12345678912.2)) - exp (log (12345678912.1));
  printf ("12345678912.2-12345678912.1: d = %g\n", d);
  d = exp (log (123456789123.2)) - exp (log (123456789123.1));
  printf ("123456789123.2-123456789123.1: d = %g\n", d);
  d = exp (log (1234567891234.2)) - exp (log (1234567891234.1));
  printf ("1234567891234.2-1234567891234.1: d = %g\n", d);
  d = exp (log (12345678912345.2)) - exp (log (12345678912345.1));
  printf ("12345678912345.2-12345678912345.1: d = %g\n", d);
  d = exp (log (123456789123456.2)) - exp (log (123456789123456.1));
  printf ("123456789123456.2-123456789123456.1: d = %g\n", d);
  d = exp (log (1234567891234567.2)) - exp (log (1234567891234567.1));
  printf ("1234567891234567.2-1234567891234567.1: d = %g\n", d);
  d = exp (log (12345678912345678.2)) - exp (log (12345678912345678.1));
  printf ("12345678912345678.2-12345678912345678.1: d = %g\n", d);
  d = exp (log (123456789123456789.2)) - exp (log (123456789123456789.1));
  printf ("123456789123456789.2-123456789123456789.1: d = %g\n", d);

  return 0;
}
    ------------8<------------ bottom cut <- top ------------->8------------

Here are the results:

ThinkPad/XPPRO/gcc-3.3.3
% rm gcctest.exe ; gcc -O -mno-cygwin -o gcctest.exe gcctest.c -lm; gcctest.exe
OR
% rm gcctest.exe ; gcc -O -ffloat-store -mno-cygwin -o gcctest.exe gcctest.c -lm; gcctest.exe
1234567.2-1234567.1: d = 0.1
12345678.2-12345678.1: d = 0.1
123456789.2-123456789.1: d = 0.0999997
1234567891.2-1234567891.1: d = 0.0999979
12345678912.2-12345678912.1: d = 0.100002
123456789123.2-123456789123.1: d = 0.100002
1234567891234.2-1234567891234.1: d = 0.100916
12345678912345.2-12345678912345.1: d = 0.0868587
123456789123456.2-123456789123456.1: d = 0.000205994
1234567891234567.2-1234567891234567.1: d = -0.0303955
12345678912345678.2-12345678912345678.1: d = -0.0839844
123456789123456789.2-123456789123456789.1: d = -7.95313

ThinkPad/XPPRO/gcc-3.3.3
% rm gcctest.exe ; gcc -O -o gcctest.exe gcctest.c -lm; gcctest.exe
OR
% rm gcctest.exe ; gcc -ffloat-store -O -o gcctest.exe gcctest.c -lm; gcctest.exe
1234567.2-1234567.1: d = 0.1
12345678.2-12345678.1: d = 0.1
123456789.2-123456789.1: d = 0.0999997
1234567891.2-1234567891.1: d = 0.099998
12345678912.2-12345678912.1: d = 0.100002
123456789123.2-123456789123.1: d = 0.100006
1234567891234.2-1234567891234.1: d = 0.10083
12345678912345.2-12345678912345.1: d = 0.0859375
123456789123456.2-123456789123456.1: d = 0
1234567891234567.2-1234567891234567.1: d = 0
12345678912345678.2-12345678912345678.1: d = 0
123456789123456789.2-123456789123456789.1: d = 0

FreeBSD-4.10/gcc-2.95.4
% rm gcctest.exe ; gcc -O -o gcctest.exe gcctest.c -lm ; gcctest.exe
OR
% rm gcctest.exe ; gcc -O -ffloat-store -o gcctest.exe gcctest.c -lm ; gcctest.exe
1234567.2-1234567.1: d = 0.1
12345678.2-12345678.1: d = 0.1
123456789.2-123456789.1: d = 0.0999997
1234567891.2-1234567891.1: d = 0.0999979
12345678912.2-12345678912.1: d = 0.100002
123456789123.2-123456789123.1: d = 0.100002
1234567891234.2-1234567891234.1: d = 0.100916
12345678912345.2-12345678912345.1: d = 0.0868587
123456789123456.2-123456789123456.1: d = 0.000198364
1234567891234567.2-1234567891234567.1: d = -0.0303955
12345678912345678.2-12345678912345678.1: d = -0.0839844
123456789123456789.2-123456789123456789.1: d = -7.95312

SPARC/Solaris9/gcc-3.4.2
% rm gcctest.exe ; gcc -O -o gcctest.exe gcctest.c -lm ; gcctest.exe
OR
% rm gcctest.exe ; gcc -O -ffloat-store -o gcctest.exe gcctest.c -lm ; gcctest.exe
1234567.2-1234567.1: d = 0.1
12345678.2-12345678.1: d = 0.1
123456789.2-123456789.1: d = 0.0999997
1234567891.2-1234567891.1: d = 0.099998
12345678912.2-12345678912.1: d = 0.100002
123456789123.2-123456789123.1: d = 0.100006
1234567891234.2-1234567891234.1: d = 0.10083
12345678912345.2-12345678912345.1: d = 0.0859375
123456789123456.2-123456789123456.1: d = 0
1234567891234567.2-1234567891234567.1: d = 0
12345678912345678.2-12345678912345678.1: d = 0
123456789123456789.2-123456789123456789.1: d = 0

Any comments?

Lester

-- 
 Prof. Lester Ingber  ingber@xxxxxxxxxx  ingber@xxxxxxxxxxxxxxxxxx
 www.ingber.com                     www.alumni.caltech.edu/~ingber

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux