2 Decimal math functions.
4 Heavily copied from http://code.google.com/p/dmath/, generalized pow to non-integer exponents.
6 Author: Pearu Peterson <pearu.peterson@gmail.com>
7 Created: February, 2007
10 __all__
= ['acos', 'asin', 'atan', 'atan2', 'ceiling', 'cos', 'cosh', 'degrees',
11 'e', 'exp', 'floor', 'golden_ratio', 'hypot', 'log', 'log10', 'pi',
12 'pow', 'radians', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh',
17 from decimal
import getcontext
18 from decimal
import Decimal
as D
21 """Compute Pi to the current precision."""
22 getcontext().prec
+= 2
23 lasts
, t
, s
, n
, na
, d
, da
= 0, D(3), 3, 1, 0, 0, 24
26 n
, na
= n
+ na
, na
+ 8
27 d
, da
= d
+ da
, da
+ 32
30 getcontext().prec
-= 2
34 """Compute the base of the natural logarithm to the current precision."""
38 """Calculate the golden ratio to the current precision."""
39 return +((1 + D(5).sqrt()) / 2)
43 """Return e raised to the power of x.
45 getcontext().prec
+= 2
46 i
, lasts
, s
, fact
, num
= 0, 0, 1, 1, 1
53 getcontext().prec
-= 2
57 """Return the cosine of x as measured in radians.
59 getcontext().prec
+= 2
60 i
, lasts
, s
, fact
, num
, sign
= 0, 0, 1, 1, 1, 1
67 s
+= num
/ fact
* sign
68 getcontext().prec
-= 2
72 """Return the sine of x as measured in radians.
74 getcontext().prec
+= 2
75 i
, lasts
, s
, fact
, num
, sign
= 1, 0, x
, 1, x
, 1
82 s
+= num
/ fact
* sign
83 getcontext().prec
-= 2
87 """Return the hyperbolic cosine of Decimal x."""
91 getcontext().prec
+= 2
92 i
, lasts
, s
, fact
, num
= 0, 0, 1, 1, 1
99 getcontext().prec
-= 2
103 """Return the hyperbolic sine of Decimal x."""
107 getcontext().prec
+= 2
108 i
, lasts
, s
, fact
, num
= 1, 0, x
, 1, x
115 getcontext().prec
-= 2
119 """Return the arc sine (measured in radians) of Decimal x."""
121 raise ValueError("Domain error: asin accepts -1 <= x <= 1")
130 return atan2(x
, D
.sqrt(1 - x
** 2))
133 """Return the arc cosine (measured in radians) of Decimal x."""
135 raise ValueError("Domain error: acos accepts -1 <= x <= 1")
144 return pi() / 2 - atan2(x
, D
.sqrt(1 - x
** 2))
147 """Return the tangent of Decimal x (measured in radians)."""
148 return +(sin(x
) / cos(x
))
151 """Return the hyperbolic tangent of Decimal x."""
152 return +(sinh(x
) / cosh(x
))
155 """Return the cotangent of Decimal x (measured in radians)."""
156 return +(cos(x
) / sin(x
))
159 """Return the hyperbolic cotangent of Decimal x."""
160 return +(cosh(x
) / sinh(x
))
163 """Return the arc tangent (measured in radians) of Decimal x."""
180 getcontext().prec
+= 2
182 y
= x_squared
/ (1 + x_squared
)
184 i
, lasts
, s
, coeff
, num
= D(0), 0, y_over_x
, 1, y_over_x
193 getcontext().prec
-= 2
197 """Return -1 for negative numbers and 1 for positive numbers."""
198 return 2 * D(x
>= 0) - 1
201 """Return the arc tangent (measured in radians) of y/x.
202 Unlike atan(y/x), the signs of both x and y are considered.
206 y_is_real
= abs_y
!= D('Inf')
210 a
= y
and atan(y
/ x
) or D(0)
217 return pi() * (D(2) * abs(x
) - x
) / (D(4) * y
)
219 return atan(sign(y
) * D('Inf'))
221 return sign(y
) * pi()
225 def log(x
, base
=None):
226 """log(x[, base]) -> the logarithm of Decimal x to the given Decimal base.
227 If the base not specified, returns the natural logarithm (base e) of x.
232 raise ValueError("Base was 1!")
238 getcontext().prec
+= 2
245 approx
= math
.log(x
, base
)
247 lasts
, s
= 0, D(repr(approx
))
250 s
= s
- 1 + x
/ exp(s
)
252 getcontext().prec
-= 2
256 """log10(x) -> the base 10 logarithm of Decimal x."""
260 """pow(x,y) -> x ** y."""
261 if isinstance(y
,(int,long)):
262 return D
.__pow
__(x
, y
)
263 if isinstance(y
,D
) and y
==D('0.5'):
265 return exp(y
* log(x
)) # this is slow
270 """degrees(x) -> converts Decimal angle x from radians to degrees"""
271 return +(x
* 180 / pi())
274 """radians(x) -> converts Decimal angle x from degrees to radians"""
275 return +(x
* pi() / 180)
278 """Return the smallest integral value >= x."""
279 return x
.to_integral(rounding
=decimal
.ROUND_CEILING
)
282 """Return the largest integral value <= x."""
283 return x
.to_integral(rounding
=decimal
.ROUND_FLOOR
)
286 """Return the Euclidean distance, sqrt(x*x + y*y)."""
287 return sqrt(x
* x
+ y
* y
)