utrig: Fix several bugs reported by @cradek

This commit is contained in:
Jeff Epler 2020-09-19 09:49:24 -05:00
parent 1817253b81
commit ec6f61c6ac

View file

@ -11,7 +11,7 @@
#
# The algorithms use range reductions and taylor polynomaials
# pylint: disable=invalid-name
# pylint: disable=invalid-name,protected-access
"""
Trig functions using jepler_udecimal
@ -46,7 +46,7 @@ Decimal('0.5646424733950353572009454457')
"""
from . import Decimal, localcontext
from . import Decimal, localcontext, getcontext, InvalidOperation
__all__ = ["acos", "asin", "atan", "cos", "sin", "tan"]
@ -58,6 +58,10 @@ def atan(x, context=None):
if not isinstance(x, Decimal):
x = Decimal(x)
ans = x._check_nans(context=context)
if ans:
return ans
with localcontext(context) as ctx:
scale = ctx.prec
@ -118,6 +122,10 @@ def sin(x, context=None):
if not isinstance(x, Decimal):
x = Decimal(x)
ans = x._check_nans(context=context)
if ans:
return ans
with localcontext(context) as ctx:
if x < 0:
return -sin(-x)
@ -147,6 +155,10 @@ def cos(x, context=None):
if not isinstance(x, Decimal):
x = Decimal(x)
ans = x._check_nans(context=context)
if ans:
return ans
with localcontext(context) as ctx:
scale = ctx.prec
ctx.prec = int(scale * 1.2)
@ -159,6 +171,10 @@ def tan(x, context=None):
if not isinstance(x, Decimal):
x = Decimal(x)
ans = x._check_nans(context=context)
if ans:
return ans
with localcontext(context) as ctx:
ctx.prec += 2
s = sin(x)
@ -171,6 +187,15 @@ def asin(x, context=None):
if not isinstance(x, Decimal):
x = Decimal(x)
ans = x._check_nans(context=context)
if ans:
return ans
context = context or getcontext()
if x.compare_total_mag(Decimal(1)) > 0:
return context._raise_error(InvalidOperation, "asin(x), |x| > 1")
with localcontext(context) as ctx:
ctx.prec += 2
r = atan(x / (1 - x * x).sqrt())
@ -182,6 +207,15 @@ def acos(x, context=None):
if not isinstance(x, Decimal):
x = Decimal(x)
ans = x._check_nans(context=context)
if ans:
return ans
context = context or getcontext()
if x.compare_total_mag(Decimal(1)) > 0:
return context._raise_error(InvalidOperation, "acos(x), |x| > 1")
with localcontext(context) as ctx:
ctx.prec += 2
r = atan((1 - x * x).sqrt() / x)