From ec6f61c6ac9d0d83ab92d8e09e38f509d022493c Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 19 Sep 2020 09:49:24 -0500 Subject: [PATCH] utrig: Fix several bugs reported by @cradek --- jepler_udecimal/utrig.py | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/jepler_udecimal/utrig.py b/jepler_udecimal/utrig.py index acbf8be..df76edb 100644 --- a/jepler_udecimal/utrig.py +++ b/jepler_udecimal/utrig.py @@ -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)