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:

>>> (1.0e18+45)-1.0e18
0.0
>>> (1.0e18+90)-1.0e17
128.0

> 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 
a multiply.

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
indexing).

> The latter of the three examples is most disappointing:
> 
> C:\>python
> 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
> 0.49999999999999994
> >>> degrees(asin(0.5))  #  == 30 
> 30.000000000000004
> >>> sin(pi)             #  == 0
> 1.2246063538223773e-016
> 
> 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?

>>> .2
0.20000000000000001

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 
purposes, irrelevant.

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
0.5
>>> print degrees(asin(0.5))  #  == 30 
30.0
>>> print sin(pi)             #  == 0
1.2246063538223773e-016

Oops, that last one didn't work.  How about:

>>> '%.15f'%sin(pi)
'0.000000000000000'

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 
the equation.




More information about the Python-list mailing list