Given integers xc, xe, yc and ye representing Decimals x = xc*10**xe and y = yc*10**ye, compute x**y. Returns a pair of integers (c, e) such that: 10**(p-1) <= c <= 10**p, and (c-1)*10**e < x**y < (c+1)*10**e in other words, c*10**e is an approximation to x**y with p digits
(xc, xe, yc, ye, p)
| 5939 | return _div_nearest(_iexp(rem, 10**p), 1000), quot - p + 3 |
| 5940 | |
| 5941 | def _dpower(xc, xe, yc, ye, p): |
| 5942 | """Given integers xc, xe, yc and ye representing Decimals x = xc*10**xe and |
| 5943 | y = yc*10**ye, compute x**y. Returns a pair of integers (c, e) such that: |
| 5944 | |
| 5945 | 10**(p-1) <= c <= 10**p, and |
| 5946 | (c-1)*10**e < x**y < (c+1)*10**e |
| 5947 | |
| 5948 | in other words, c*10**e is an approximation to x**y with p digits |
| 5949 | of precision, and with an error in c of at most 1. (This is |
| 5950 | almost, but not quite, the same as the error being < 1ulp: when c |
| 5951 | == 10**(p-1) we can only guarantee error < 10ulp.) |
| 5952 | |
| 5953 | We assume that: x is positive and not equal to 1, and y is nonzero. |
| 5954 | """ |
| 5955 | |
| 5956 | # Find b such that 10**(b-1) <= |y| <= 10**b |
| 5957 | b = len(str(abs(yc))) + ye |
| 5958 | |
| 5959 | # log(x) = lxc*10**(-p-b-1), to p+b+1 places after the decimal point |
| 5960 | lxc = _dlog(xc, xe, p+b+1) |
| 5961 | |
| 5962 | # compute product y*log(x) = yc*lxc*10**(-p-b-1+ye) = pc*10**(-p-1) |
| 5963 | shift = ye-b |
| 5964 | if shift >= 0: |
| 5965 | pc = lxc*yc*10**shift |
| 5966 | else: |
| 5967 | pc = _div_nearest(lxc*yc, 10**-shift) |
| 5968 | |
| 5969 | if pc == 0: |
| 5970 | # we prefer a result that isn't exactly 1; this makes it |
| 5971 | # easier to compute a correctly rounded result in __pow__ |
| 5972 | if ((len(str(xc)) + xe >= 1) == (yc > 0)): # if x**y > 1: |
| 5973 | coeff, exp = 10**(p-1)+1, 1-p |
| 5974 | else: |
| 5975 | coeff, exp = 10**p-1, -p |
| 5976 | else: |
| 5977 | coeff, exp = _dexp(pc, -(p+1), p+1) |
| 5978 | coeff = _div_nearest(coeff, 10) |
| 5979 | exp += 1 |
| 5980 | |
| 5981 | return coeff, exp |
| 5982 | |
| 5983 | def _log10_lb(c, correction = { |
| 5984 | '1': 100, '2': 70, '3': 53, '4': 40, '5': 31, |