1111#
1212# The algorithms use range reductions and taylor polynomaials
1313
14- # pylint: disable=invalid-name
14+ # pylint: disable=invalid-name,protected-access
1515
1616"""
1717Trig functions using jepler_udecimal
4646
4747"""
4848
49- from . import Decimal , localcontext
49+ from . import Decimal , localcontext , getcontext , InvalidOperation
5050
5151__all__ = ["acos" , "asin" , "atan" , "cos" , "sin" , "tan" ]
5252
@@ -58,6 +58,10 @@ def atan(x, context=None):
5858 if not isinstance (x , Decimal ):
5959 x = Decimal (x )
6060
61+ ans = x ._check_nans (context = context )
62+ if ans :
63+ return ans
64+
6165 with localcontext (context ) as ctx :
6266 scale = ctx .prec
6367
@@ -118,6 +122,10 @@ def sin(x, context=None):
118122 if not isinstance (x , Decimal ):
119123 x = Decimal (x )
120124
125+ ans = x ._check_nans (context = context )
126+ if ans :
127+ return ans
128+
121129 with localcontext (context ) as ctx :
122130 if x < 0 :
123131 return - sin (- x )
@@ -147,6 +155,10 @@ def cos(x, context=None):
147155 if not isinstance (x , Decimal ):
148156 x = Decimal (x )
149157
158+ ans = x ._check_nans (context = context )
159+ if ans :
160+ return ans
161+
150162 with localcontext (context ) as ctx :
151163 scale = ctx .prec
152164 ctx .prec = int (scale * 1.2 )
@@ -159,6 +171,10 @@ def tan(x, context=None):
159171 if not isinstance (x , Decimal ):
160172 x = Decimal (x )
161173
174+ ans = x ._check_nans (context = context )
175+ if ans :
176+ return ans
177+
162178 with localcontext (context ) as ctx :
163179 ctx .prec += 2
164180 s = sin (x )
@@ -171,6 +187,15 @@ def asin(x, context=None):
171187 if not isinstance (x , Decimal ):
172188 x = Decimal (x )
173189
190+ ans = x ._check_nans (context = context )
191+ if ans :
192+ return ans
193+
194+ context = context or getcontext ()
195+
196+ if x .compare_total_mag (Decimal (1 )) > 0 :
197+ return context ._raise_error (InvalidOperation , "asin(x), |x| > 1" )
198+
174199 with localcontext (context ) as ctx :
175200 ctx .prec += 2
176201 r = atan (x / (1 - x * x ).sqrt ())
@@ -182,6 +207,15 @@ def acos(x, context=None):
182207 if not isinstance (x , Decimal ):
183208 x = Decimal (x )
184209
210+ ans = x ._check_nans (context = context )
211+ if ans :
212+ return ans
213+
214+ context = context or getcontext ()
215+
216+ if x .compare_total_mag (Decimal (1 )) > 0 :
217+ return context ._raise_error (InvalidOperation , "acos(x), |x| > 1" )
218+
185219 with localcontext (context ) as ctx :
186220 ctx .prec += 2
187221 r = atan ((1 - x * x ).sqrt () / x )
0 commit comments