problem with the 'math' module in 2.5?

C

Chris

from math import *1.0

The cosine function works fine, but I'm getting weird answers for sine.
Is this a bug? Am I doing something wrong?
 
M

mensanator

Chris said:
1.0

The cosine function works fine, but I'm getting weird answers for sine.
Is this a bug? Am I doing something wrong?

What answer do you suppose you get in version 2.4?
 
M

Max Erickson

Chris said:
1.0

The cosine function works fine, but I'm getting weird answers for
sine. Is this a bug? Am I doing something wrong?
From help(math) in an interactive window:


DESCRIPTION
This module is always available. It provides access to the
mathematical functions defined by the C standard.

So what you are seeing is the behavior of the C library being exposed.


Try sin(pi*0.5) to see similar behavior to cos(pi) or cos(pi*2).
 
C

Carsten Haese

On 14 Oct 2006 20:33:13 -0700, Chris wrote
1.0

The cosine function works fine, but I'm getting weird answers for sine.
Is this a bug? Am I doing something wrong?

You're apparently not correctly reading python's answer to sin(pi).
1.2246063538223773e-016 is the scientific notation for the number
0.00000000000000012246063538223773, which is pretty darn close to zero, the
result you probably expected.

You're not getting *exactly* zero because you're not passing in *exactly* pi
but a close approximation of pi.

I'll leave it as an exercise for the reader to explain why cosine seems to
work fine. Hint: Look at cos(pi/2) and sin(pi/2).

-Carsten
 
C

Chris

I don't understand what that number came from. My calculator gives me
cos(pi*.5) = 0, and my interpreter gives me cos(pi*0.5) =
6.1230317691118863e-017.
 
B

Ben Finney

Chris said:
Oh, ok that explains it. Is that why my 16-bit calculator gives me
0?

Your calculator is probably doing rounding without you asking for it.

Python refuses to guess what you want, and gives you the information
available.
 
G

Gary Herron

Ben said:
Your calculator is probably doing rounding without you asking for it.
Yes. Almost all calculators have 1 or 2 guard digits. These are extra
digits beyond what is shown on the display. All calculations are done at
that higher precision and the result are rounded to the precision of the
display for the user's benefit.

This satisfies users who know nothing about the numerical imprecision of
finite digit arithmetic. Python makes the opposite assumption that we
are are adults here and can handle the full knowledge, slight
imprecision and all.

Dr. Gary Herron
 
P

Paddy

Ben said:
Your calculator is probably doing rounding without you asking for it.

Python refuses to guess what you want, and gives you the information
available.
Hi Ben,
I don't think Python should take too much credit here. Floating point
calcuations are subject to rounding. Sometimes it shows.

- Pad.
 
B

Ben Finney

Paddy said:
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.
 
A

andy2O

Chris said:
sin(pi*0.5) is what I expected, but I expected to get 0 for sin(pi).

Computers in general, and Python too, usually use floating point
arithmetic in which all numbers are approximated by rational numbers of
a particular form (see http://en.wikipedia.org/wiki/Floating_point for
details).

1) pi is an irrational number, so it *cannot* be represented exactly in
floating point. Therefore the value of pi in your call to the sin
function is definitely, proveably, *not* exactly equal to the true
value of pi.

2) So, even if the function "sin" could be evaluated exactly, the fact
that you are not evaluating it exactly at the true value of pi, but
instead at a good but imperfect approximation to this value, means that
the sine function *should not* give the result = 0 for your request!

3) The function sin is also evaluated to only a finite degree of
precision - just like everything else in floating point arithmetic.
Therefore you should not expect absolutely precise results. Instead,
you need to understand the limitations of floating point arithmetic,
understand the precision you *can* expect, and work within these
bounds. It's a good system, but you do need to understand its
limitations. The links other people have posted are good resources for
this.

Best wishes,
andy
 
S

Steven D'Aprano

Paddy said:
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?
 
D

Dennis Lee Bieber

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:
Well... I'd expect that, for any reasonably modern machine, the
library is just invoking some functions built into the floating point
unit of the processor. You'd have to ask the chip makers... (I seem to
recall that, for small angles -- in radians -- the sine can be
approximated by returning the angle itself:

)



A calculator, OTOH, probably doesn't have a floating point processor
-- many of them were built around 4-8bit processors using BCD notation
(two decimal digits per byte), and likely had look-up tables, with
interpolation, in ROM for the transcendental functions. The electronic
equivalent of looking up such values in a table in the CRC (or similar)
standard math tables book(s).
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top