math module broken?
Christopher T King
squirrel at WPI.EDU
Fri Jul 23 19:40:36 CEST 2004
On 23 Jul 2004, Jon Wright wrote:
> There was some discussion about this recently over in
> comp.lang.fortran, arising when someone queried sin/cos/tan etc for
> very large angles (represented in floating point, eg: sin(1.0E18)).
> Reduction (angle modulo 2pi) is considerably easier if you use a
> *rational* unit for measuring angles, as the answer can remain exact
> in terms of the particular number represented in floating point.
Reduction... from 1.0e18?! Of course that doesn't work with radians, it
doesn't even works with degrees! 64-bit floating point numbers are only
accurate to +-64.0 at that magnitude:
> Without using an irrational number, exact representations of angles
> can actually exist where you also have exact representations of sines
> and cosines. With radians you can only represent zero exactly, and
> below it seems not even that!
So don't store your angles as radians. Mangle them, reduce them, whatever
if degrees / grads, and then convert them to radians before passing them
to the trig functions.
> Can someone supply a real concrete example where there is a reason to
> prefer radians when computing sin/cos/tan? (Not their derivatives!)
Because that's how the processor does it. If degrees were used in the
library, every sin() would have to be prefixed at the assembly level with
Derivates (and other mathematical reasons) are also perfectly valid
example. Every math / physics formula involving trigonometry uses
radians. If sin() accepted degrees, every formula I expressed in Python
would be littered with radian -> degree conversions. Quite confusing for
a researcher picking up Python for the first time. Python's done a good
job at winning over academia (mostly due to Numeric and numarray);
switching to degrees is a step in the wrong direction.
I'll skip over the obvious argument of purity here (i.e. switching trig
functions to degrees is the equivalent of switching to 1-based array
> The latter of the three examples is most disappointing:
> Python 2.3.3 (#51, Dec 18 2003, 20:22:39) [MSC v.1200 32 bit (Intel)]
> on win32
> Type "help", "copyright", "credits" or "license" for more information.
> >>> from math import sin,asin,pi
> >>> sin(pi/6) # == 0.5
> >>> degrees(asin(0.5)) # == 30
> >>> sin(pi) # == 0
> I understand why this fails - I just think the world is wrong.
> Represent angles using some rational fraction of a circle and all this
> crap goes away. Why convert to a unit which eliminates the possibility
> of an exact representation of any result at all?
The error in your calculations is of the same order of magnitude as that
of the error introduced by the representation of numbers as floating point
(not surprisingly, since the magnitude of the error of the value of pi is
caused by that same feature), and is therefore, for all practical
What's more, because any method of calculating sines (including that used
by the processor) requires that its arguments be in radians, there's no
way around this error, no matter how hard you try (unless, of course, you
implement an 80- or even 128-bit floating point arithmetic library, in
which case it won't be included in Python because it will be an order of
magnitude slower than using the math coprocessor).
> The microsoft calculator has a checkbox for switching between degrees
> and radians and gets all of the analytical results above correct. We
> live in a mad world....
I'm certain that's because it limits (reasonably) the accuracy of its
output, just like Python can do:
>>> print sin(pi/6) # == 0.5
>>> print degrees(asin(0.5)) # == 30
>>> print sin(pi) # == 0
Oops, that last one didn't work. How about:
Personally, I'd like to see an application where any accuracy greater than
that is needed... and anyways, just how often do you expect angles of 30,
45, 60, and 90 degrees to come up in regular calculations? The chance of
one of them occuring randomly is infinitesmally small (except for in
high-school geometry homework, of course), and when they do come up
deterministically in a formula, they are almost always optimized out of
More information about the Python-list