MCPcopy Index your code
hub / github.com/python/cpython / _iexp

Function _iexp

Lib/_pydecimal.py:5868–5903  ·  view source on GitHub ↗

Given integers x and M, M > 0, such that x/M is small in absolute value, compute an integer approximation to M*exp(x/M). For 0 <= x/M <= 2.4, the absolute error in the result is bounded by 60 (and is usually much smaller).

(x, M, L=8)

Source from the content-addressed store, hash-verified

5866_log10_digits = _Log10Memoize().getdigits
5867
5868def _iexp(x, M, L=8):
5869 """Given integers x and M, M > 0, such that x/M is small in absolute
5870 value, compute an integer approximation to M*exp(x/M). For 0 <=
5871 x/M <= 2.4, the absolute error in the result is bounded by 60 (and
5872 is usually much smaller)."""
5873
5874 # Algorithm: to compute exp(z) for a real number z, first divide z
5875 # by a suitable power R of 2 so that |z/2**R| < 2**-L. Then
5876 # compute expm1(z/2**R) = exp(z/2**R) - 1 using the usual Taylor
5877 # series
5878 #
5879 # expm1(x) = x + x**2/2! + x**3/3! + ...
5880 #
5881 # Now use the identity
5882 #
5883 # expm1(2x) = expm1(x)*(expm1(x)+2)
5884 #
5885 # R times to compute the sequence expm1(z/2**R),
5886 # expm1(z/2**(R-1)), ... , exp(z/2), exp(z).
5887
5888 # Find R such that x/2**R/M <= 2**-L
5889 R = _nbits((x<<L)//M)
5890
5891 # Taylor series. (2**L)**T > M
5892 T = -int(-10*len(str(M))//(3*L))
5893 y = _div_nearest(x, T)
5894 Mshift = M<<R
5895 for i in range(T-1, 0, -1):
5896 y = _div_nearest(x*(Mshift + y), Mshift * i)
5897
5898 # Expansion
5899 for k in range(R-1, -1, -1):
5900 Mshift = M<<(k+2)
5901 y = _div_nearest(y*(y+Mshift), Mshift)
5902
5903 return M+y
5904
5905def _dexp(c, e, p):
5906 """Compute an approximation to exp(c*10**e), with p decimal places of

Callers 1

_dexpFunction · 0.85

Calls 2

strFunction · 0.85
_div_nearestFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…