From: apm233m@vaxc.cc.monash.edu.au Subject: Re: Not quite bug in math stuff Date: Mon, 14 Dec 1992 06:31:57 GMT
In article <1992Dec13.032953.4975@tc.cornell.edu>, kutcha@eos.acm.rpi.edu (Phillip Rzewski) writes:
>
> I don't do much stuff with math under Linux, so I never ran into this
> before. I'm sure someone else has come across this, it's probably quite
> documented somewhere. But it took me rather by surprise.
>
> Consider the program:
>
> #include <stdio.h>
> #include <math.h>
>
> int main(void)
> {
> double d;
> long l;
>
> d = pow(2.0, 1.0);
> printf("%1.32f\n", d);
> l = (long) d;
> printf("%d\n", l);
>
> return 0;
> }
>
> And of course the output:
>
> 1.99999999999999977795539507496869
> 1
>
> Now, I understand how keen it is that math software speeds things up
> by using logarithms, giving us results like this. However, I know that there
> are systems out there where one doesn't notice it quite so much. The
> program I was originally working with on Linux (not like the one above :) )
> was originally something I wrote under VAX C on a VMS system, and I got
> just what I thought in the long (in other words, 2).
>
> Of course, I was able to fix this by simply adding 0.5 to the double
> and then casting it to long. It just seems kinda icky to have to do it that
> way. I mean, this means that every person who tries to do something like I
> did above (which I would think is quite a few) would have to have this same
> weird thing happen to them and learn how to correct it.
>
> I'm not one to make demands or anything, but the math people might
> consider fixing this?
What version of the kernel and libraries are you using?
Using the FPU emulator with 0.98.6 (I don't have a co-processor), I get
2.00000000000000000000000 [etc]
with your program.
Perhaps you are using the obsolete 'soft' math libs.
Your question does raise a valid point though. It would certainly be
nice if the most accurate answer were always given for floating point
problems. Alas, this is simply not possible. The use of finite precision
arithmetic should always be accompanied by an appropriate degree of care.
Linux is often not bad for simple problems because it runs the co-processor
at ~64 bit precision (doubles are ~53 bit precision under Linux gcc).
However, even simple programs can give results which are worse than you
might expect. Consider the following little program:
#include <stdio.h>
void main(void)
{ double d;
d = 1.0; d = d/3.0;
printf("%g\n", 1.0-d*3.0); }
This will give a non-zero result (compile with no optimizations).
But if you try:
#include <stdio.h>
void main(void)
{ double d, e;
d = 1.0; e = 3.0;
printf("%g\n", 1.0-d/3.0*e); }
Then because the intermediate result 0.333333... is kept on the co-
processor stack in this case, a different result is obtained (it
happens to be zero).
-- =============== Bill Metzenthen Mathematics Department Monash University Australia