# problem with the 'math' module in 2.5?

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Mon Oct 16 01:10:25 CEST 2006

On Sun, 15 Oct 2006 20:03:18 +1000, Ben Finney wrote:

>
>> Ben Finney wrote:
>> > Your calculator is probably doing rounding without you asking for
>> > it.
>> >
>> > Python refuses to guess what you want, and gives you the
>> > information available.
>>
>> I don't think Python should take too much credit here.
>
> I don't understand what you could mean by this. Credit for "giv[ing]
> you the information available"? That's exactly what it's doing.
>
>> Floating point calcuations are subject to rounding. Sometimes it
>> shows.
>
> And Python is showing it, rather than hiding it. It certainly isn't
> doing any rounding unless asked to do so.

Python simply exposes whatever the C maths library does. The C maths
library is almost certainly doing some rounding: floats have only a finite
precision, which generally means the designer of the math library has two
choices: just truncate (chop) the calculation, or carry extra guard digits
(or bits) and round down. Most systems these days use guard digits, as
that is more accurate than truncating to a fixed precision.

If you mean that Python isn't doing *extra* rounding, above and beyond
what the C library is doing, you're correct. But rounding is happening.

This is a useful resource:

"What every computer scientist should know about floating-point
arithmetic"
http://docs.sun.com/source/806-3568/ncg_goldberg.html

To go back to the Original Poster's problem, he pointed out that his "16
bit calculator" gave a more accurate (but less precise) answer for
sin(pi), namely 0, instead of the more precise (but less accurate)
1.2246063538223773e-016 that Python reported. That just goes to show that,
sometimes, extra precision in floating point maths is a bad thing -- a
less precise library would actually have given a more correct answer.

This isn't strictly a Python question, but if there is anybody out there
who knows what the C library is doing, I'd appreciate an answer: since
sine is periodic, doesn't it make sense to reduce the argument modulo pi
before calculating the sine? Something like this:

def _sin(x):
x = x % math.pi
return math.sin(x)

Yes, you lose precision for large values of x because of the modulo, and
because math.pi isn't precisely pi, but that's got to be better than
losing precision for moderate values of x, surely? Have I missed something?

--
Steve.