From: David Kirkby on
The value of E^1 is
2.71828182845904523536028747135266249775724709369995957496696...

Trying this noddy C program, I get a different answer from gcc than I
do from Sun Studio on SPARC. GCC gets it more accurate than Sun
Studio. On Open Solaris, using a Xeon processor, the two compilers
give the same result. I get the same result on HP-UX with both GCC and
HP's native compiler.

But for reasons unknown, Sun Studio gives a different answer on
SPARC.

drkirkby(a)kestrel:~$ cat exp.c
#include <math.h>
#include <stdio.h>

int main() {
printf("%.16lf\n",exp(1.0));
}

This data below is from a Sun Netra T1 SPARC (sun4u architecture) of
mine. I've tried on another SPARC, in that case a T5240 (sun4v) and
get exactly the same results.

drkirkby(a)kestrel:~$ uname -a
SunOS kestrel 5.10 Generic_141444-09 sun4u sparc SUNW,UltraAX-i2
drkirkby(a)kestrel:~$ gcc exp.c
drkirkby(a)kestrel:~$ ./a.out
2.7182818284590451
drkirkby(a)kestrel:~$ /opt/sunstudio12.1/bin/cc -lm exp.c
drkirkby(a)kestrel:~$ ./a.out
2.7182818284590455

Now, when I do this on Open Solaris, I get the same result with each
compiler.

bash-3.2$ uname -a
SunOS hawk 5.11 snv_111b i86pc i386 i86pc
bash-3.2$ gcc exp.c
bash-3.2$ ./a.out
2.7182818284590451
bash-3.2$ /opt/sunstudio12.1/bin/cc -lm exp.c
bash-3.2$ ./a.out
2.7182818284590451

I also tried this on HP-UX, and get the same (correct) result with
both the
native HP compiler and with gcc.

-bash-4.0$ uname -a
HP-UX hpbox B.11.11 U 9000/785 2016698240 unlimited-user license
-bash-4.0$ gcc exp.c
-bash-4.0$ ./a.out
2.7182818284590451
-bash-4.0$ cc -lm exp.c
-bash-4.0$ ./a.out
2.7182818284590451
From: Michael Laajanen on
Hi,

David Kirkby wrote:
> The value of E^1 is
> 2.71828182845904523536028747135266249775724709369995957496696...
>
> Trying this noddy C program, I get a different answer from gcc than I
> do from Sun Studio on SPARC. GCC gets it more accurate than Sun
> Studio. On Open Solaris, using a Xeon processor, the two compilers
> give the same result. I get the same result on HP-UX with both GCC and
> HP's native compiler.
>
> But for reasons unknown, Sun Studio gives a different answer on
> SPARC.
>
> drkirkby(a)kestrel:~$ cat exp.c
> #include <math.h>
> #include <stdio.h>
>
> int main() {
> printf("%.16lf\n",exp(1.0));
> }
>
> This data below is from a Sun Netra T1 SPARC (sun4u architecture) of
> mine. I've tried on another SPARC, in that case a T5240 (sun4v) and
> get exactly the same results.
>
> drkirkby(a)kestrel:~$ uname -a
> SunOS kestrel 5.10 Generic_141444-09 sun4u sparc SUNW,UltraAX-i2
> drkirkby(a)kestrel:~$ gcc exp.c
> drkirkby(a)kestrel:~$ ./a.out
> 2.7182818284590451
> drkirkby(a)kestrel:~$ /opt/sunstudio12.1/bin/cc -lm exp.c
> drkirkby(a)kestrel:~$ ./a.out
> 2.7182818284590455
>
> Now, when I do this on Open Solaris, I get the same result with each
> compiler.
>
> bash-3.2$ uname -a
> SunOS hawk 5.11 snv_111b i86pc i386 i86pc
> bash-3.2$ gcc exp.c
> bash-3.2$ ./a.out
> 2.7182818284590451
> bash-3.2$ /opt/sunstudio12.1/bin/cc -lm exp.c
> bash-3.2$ ./a.out
> 2.7182818284590451
>
> I also tried this on HP-UX, and get the same (correct) result with
> both the
> native HP compiler and with gcc.
>
> -bash-4.0$ uname -a
> HP-UX hpbox B.11.11 U 9000/785 2016698240 unlimited-user license
> -bash-4.0$ gcc exp.c
> -bash-4.0$ ./a.out
> 2.7182818284590451
> -bash-4.0$ cc -lm exp.c
> -bash-4.0$ ./a.out
> 2.7182818284590451
I get the same results, also tried sunstudioexpress_2009.03

/michael
From: Chris Ridd on
On 2009-12-31 09:02:43 +0000, Michael Laajanen said:

> Hi,
>
> David Kirkby wrote:
>> The value of E^1 is
>> 2.71828182845904523536028747135266249775724709369995957496696...
>>
>> Trying this noddy C program, I get a different answer from gcc than I
>> do from Sun Studio on SPARC. GCC gets it more accurate than Sun
>> Studio. On Open Solaris, using a Xeon processor, the two compilers
>> give the same result. I get the same result on HP-UX with both GCC and
>> HP's native compiler.
>>
>> But for reasons unknown, Sun Studio gives a different answer on
>> SPARC.
>>
>> drkirkby(a)kestrel:~$ cat exp.c
>> #include <math.h>
>> #include <stdio.h>
>>
>> int main() {
>> printf("%.16lf\n",exp(1.0));
>> }
>>
>> This data below is from a Sun Netra T1 SPARC (sun4u architecture) of
>> mine. I've tried on another SPARC, in that case a T5240 (sun4v) and
>> get exactly the same results.
>>
>> drkirkby(a)kestrel:~$ uname -a
>> SunOS kestrel 5.10 Generic_141444-09 sun4u sparc SUNW,UltraAX-i2
>> drkirkby(a)kestrel:~$ gcc exp.c
>> drkirkby(a)kestrel:~$ ./a.out
>> 2.7182818284590451
>> drkirkby(a)kestrel:~$ /opt/sunstudio12.1/bin/cc -lm exp.c
>> drkirkby(a)kestrel:~$ ./a.out
>> 2.7182818284590455
>>
>> Now, when I do this on Open Solaris, I get the same result with each
>> compiler.
>>
>> bash-3.2$ uname -a
>> SunOS hawk 5.11 snv_111b i86pc i386 i86pc
>> bash-3.2$ gcc exp.c
>> bash-3.2$ ./a.out
>> 2.7182818284590451
>> bash-3.2$ /opt/sunstudio12.1/bin/cc -lm exp.c
>> bash-3.2$ ./a.out
>> 2.7182818284590451
>>
>> I also tried this on HP-UX, and get the same (correct) result with
>> both the
>> native HP compiler and with gcc.
>>
>> -bash-4.0$ uname -a
>> HP-UX hpbox B.11.11 U 9000/785 2016698240 unlimited-user license
>> -bash-4.0$ gcc exp.c
>> -bash-4.0$ ./a.out
>> 2.7182818284590451
>> -bash-4.0$ cc -lm exp.c
>> -bash-4.0$ ./a.out
>> 2.7182818284590451
> I get the same results, also tried sunstudioexpress_2009.03

I don't play with floating point much, but are there any
compiler/linker options that will change things?

--
Chris

From: Stuart Biggar on
On 12/30/09 5:52 PM, David Kirkby wrote:
> The value of E^1 is
> 2.71828182845904523536028747135266249775724709369995957496696...
>
> Trying this noddy C program, I get a different answer from gcc than I
> do from Sun Studio on SPARC. GCC gets it more accurate than Sun
> Studio. On Open Solaris, using a Xeon processor, the two compilers
> give the same result. I get the same result on HP-UX with both GCC and
> HP's native compiler.
>
> But for reasons unknown, Sun Studio gives a different answer on
> SPARC.
>
> drkirkby(a)kestrel:~$ cat exp.c
> #include<math.h>
> #include<stdio.h>
>
> int main() {
> printf("%.16lf\n",exp(1.0));
> }
>
> This data below is from a Sun Netra T1 SPARC (sun4u architecture) of
> mine. I've tried on another SPARC, in that case a T5240 (sun4v) and
> get exactly the same results.
>
> drkirkby(a)kestrel:~$ uname -a
> SunOS kestrel 5.10 Generic_141444-09 sun4u sparc SUNW,UltraAX-i2
> drkirkby(a)kestrel:~$ gcc exp.c
> drkirkby(a)kestrel:~$ ./a.out
> 2.7182818284590451
> drkirkby(a)kestrel:~$ /opt/sunstudio12.1/bin/cc -lm exp.c
> drkirkby(a)kestrel:~$ ./a.out
> 2.7182818284590455
>
> Now, when I do this on Open Solaris, I get the same result with each
> compiler.
>
> bash-3.2$ uname -a
> SunOS hawk 5.11 snv_111b i86pc i386 i86pc
> bash-3.2$ gcc exp.c
> bash-3.2$ ./a.out
> 2.7182818284590451
> bash-3.2$ /opt/sunstudio12.1/bin/cc -lm exp.c
> bash-3.2$ ./a.out
> 2.7182818284590451
>
> I also tried this on HP-UX, and get the same (correct) result with
> both the
> native HP compiler and with gcc.
>
> -bash-4.0$ uname -a
> HP-UX hpbox B.11.11 U 9000/785 2016698240 unlimited-user license
> -bash-4.0$ gcc exp.c
> -bash-4.0$ ./a.out
> 2.7182818284590451
> -bash-4.0$ cc -lm exp.c
> -bash-4.0$ ./a.out
> 2.7182818284590451

David,

I'm no expert in floating point but do use it. I wouldn't
expect different compilers on different architectures to get
consistent results in double precision to better than what
is defined in float.h (from a SPARC running Solaris 10U4):

DBL_DIG is defined as 15 and
DBL_EPSILON is defined as a bit over 2.2e-16

So I wouldn't expect computations in double precision to
have more than 15 significant digits. Some (few) values may
be exact but most will not be.

If you need better precision, try 80-bit on x86 or quad
precision on SPARC (LDBL). That should result in 18 or 33
significant digits. In any case, floating point is only
a (probably inaccurate to some degree) representation of
the real number you are trying to calculate. There are
all sorts of traps for the unwary in floating point. I've
found that you have to be very careful how you compute
things - mathematically equal ways of representing a
quantity can compute quite differently with precision
VERY much worse than you might expect. Extended precision
can help some but isn't the real fix (and it may slow
things down considerably).

Stuart

From: David Kirkby on
On Dec 31, 12:59 pm, Stuart Biggar <sbig...(a)email.arizona.edu> wrote:
> David,
>
> I'm no expert in floating point but do use it.  I wouldn't
> expect different compilers on different architectures to get
> consistent results in double precision to better than what
> is defined in float.h (from a SPARC running Solaris 10U4):
>
> DBL_DIG is defined as 15 and
> DBL_EPSILON is defined as a bit over 2.2e-16
>
> So I wouldn't expect computations in double precision to
> have more than 15 significant digits.  Some (few) values may
> be exact but most will not be.
>
> If you need better precision, try 80-bit on x86 or quad
> precision on SPARC (LDBL).  That should result in 18 or 33
> significant digits.  In any case, floating point is only
> a (probably inaccurate to some degree) representation of
> the real number you are trying to calculate.  There are
> all sorts of traps for the unwary in floating point.  I've
> found that you have to be very careful how you compute
> things - mathematically equal ways of representing a
> quantity can compute quite differently with precision
> VERY much worse than you might expect.  Extended precision
> can help some but isn't the real fix (and it may slow
> things down considerably).
>
> Stuart

Thank you Stuart.

But the issue here is not simply different compilers on different
architectures, but different compilers on the *same* architecture.

Sun Studio on SPARC is unique among all the different compilers tried
(gcc, HP, Sun Studio) on different platforms (x86, SPARC, PA-RISC and
some unknown to me processor on which AIX 6.1 is running). I can only
check with gcc on AIX - there is no valid IBM compiler.

1) The correct answer is
2.71828182845904523536028747135266249775724709369995957496696... goes
on forever.

2) Rounded to within the limits specific by DBL_EPSILON in float.h
(2.2204460492503130808473 x 10^-16), E should be 2.7182818284590451 (a
better answer, using no more decimal digits would be
2.7182818284590452)

3) Sun Studio on SPARC gives: 2.7182818284590455, which is not a
correctly rounded representation of E.

4) Every other compiler / OS gives the the correctly rounded number.

* GCC on SPARC gives 2.7182818284590451
* Sun Studio on Solaris x86 gives 2.7182818284590451
* GCC on Solaris x86 gives 2.7182818284590451
* GCC on Linux x86 gives 2.7182818284590451
* HP's compiler on HP-UX gives 2.7182818284590451
* GCC on HP-UX gives 2.7182818284590451
* GCC on AIX gives 2.7182818284590451

That does strike me as a bit strange, given E is a fundamental
constant. But perhaps I should not be too surprised.

I do not need higher precision for this. The problem was discovered
when the self-tests were run on the Sage open-source maths software.

http://www.sagemath.org/

of which I am one of the developers. (My main interest has been
porting Sage to Solaris.) A test for the value of E using machine
precision was failing, which led to some further investigations.

There are libraries in Sage which implement arbitrary precision
computations of floating point numbers, but that's not the issue
here.


Dave