correct round of reals?

Michael Hudson mwh21 at cam.ac.uk
Sat May 13 09:13:55 EDT 2000


Peter Schneider-Kamp <petersc at stud.ntnu.no> writes:

> Fredrik Lundh wrote:
> > 
> > def rint(v, m=4503599627370496.0):
> >     if abs(v) > m:
> >         return v
> >     if v > 0:
> >         return (v + m) - m
> >     else:
> >         return (v - m) + m
> 
> That is very nice and works fine in Python, but the
> romans don't go home in that "C" language:
> 
> #define MAX_DOUBLE_INT 4503599627370496.0
> double rint(x) double x; {
>         if (abs(x) > MAX_DOUBLE_INT)
>                 return x;
>         if (x > 0)
>                 return (x+MAX_DOUBLE_INT)-MAX_DOUBLE_INT;
>         else
>                 return (x-MAX_DOUBLE_INT)+MAX_DOUBLE_INT;
> }
> 
> Using this rint in the mathmodule.c I get:
> math.rint(0.7) == 0.700195
> 
> What's wrong?

It's the C compilers charming belief that floating point arithmetic is
associative - "ooh look the stupid luser doesn't neeed to both add and
subtract that number from x".  So you're fighting the optimiser.  I've
managed to come up with code that works with gcc at lower optimisation
settings, but as soon as you crank it up, gcc manages to work out what
I'm up to... I guess you could use functions in different object files
to do this, but that's going too far.

I'd guess there is some switch or pragma that will stop gcc reordering
floating point operations, but it'll be compiler dependent.  Joys.

Anyone know a more general technique?

what-fun-fp-is-ly y'rs
M.

-- 
112. Computer Science is embarrassed by the computer.
     -- Alan Perlis, http://www.cs.yale.edu/~perlis-alan/quotes.html



More information about the Python-list mailing list