[Python-ideas] Fwd: Trigonometry in degrees

Steven D'Aprano steve at pearwood.info
Mon Jun 11 20:48:36 EDT 2018


On Tue, Jun 12, 2018 at 10:57:18AM +1200, Greg Ewing wrote:
> Steven D'Aprano wrote:
> >sin(3°) is:
> >
> >-1/2 (-1)^(29/60) ((-1)^(1/60) - 1) (1 + (-1)^(1/60))
> >
> >This proposal was supposed to *simplify* the trig functions for 
> >non-mathematicians, not make them mind-bogglingly complicated.
> 
> I don't think anyone is going to complain about sin(3°) not
> being exact, whatever units are being used. This discussion
> is only about the rational values.

Precisely. They are the values I'm talking about.

If you're serious about only supporting only the rational values, then 
the implementation is trivial and we can support both degrees and 
radians easily.

def sin(angle):  # radians
    if angle == 0:
        return 0
    raise ValueError("sorry, no rational sine for that angle")

def sind(angle):  # degrees
    angle %= 360
    rational_values = {
            0: 0,    30: 0.5,   90: 1,  150: 0.5,
            180: 0, 210: -0.5, 270: -1, 330: -0.5
            }
    if angle in rational_values:
        return rational_values[angle]
    raise ValueError("sorry, no rational sine for that angle")


Exceedingly simple, and exceedingly useless. Which was my point: 
supporting only the rational values is pointless, because there are only 
a handful of them. We either have to support full-blown symbolic 
results, or we have rational APPROXIMATIONS to the true value.

I'm responding to a proposal that explicitly suggested using fractions 
to do "real (not float) math", which I read as "no approximations". I 
imagine that Michael thought that by using fractions, we can calculate 
exact rational results for sine etc without floating point rounding 
errors. No we cannot, except for the values above.

If "not float" is serious, then with the exception of the above values, 
*none* of the values will be rational and we either can't return a value 
(except for the above) or we have to use symbolic maths.

Using fractions is not a magic panacea that lets you calculate exact 
answers just by swapping floats to fractions.


> I wonder whether another solution would be to provide a
> set of "newbie math" functions that round their results.
[...]
> Yes, I know, this just pushes the surprises somewhere
> else, but so does every solution.

No, that's really not true of every solution.

The initial proposal is fine: a separate set of trig functions that take 
their arguments in degrees would have no unexpected surprises (only the 
expected ones). With a decent implementation i.e. not this one:

    # don't do this
    def sind(angle):
        return math.sin(math.radians(angle))

and equivalent for cos, we ought to be able to get correctly rounded 
values for nearly all the "interesting" angles of the circle, without 
those pesky rounding issues caused by π not being exactly representable 
as a float.

There will still be rounding errors, because we're dealing with numbers 
like sqrt(2) etc, but with IEEE-754 maths, they'll be correctly 
rounded.


-- 
Steve


More information about the Python-ideas mailing list