Class to compute, store, and allow retrieval of, digits of the constant log(10) = 2.302585.... This constant is needed by Decimal.ln, Decimal.log10, Decimal.exp and Decimal.__pow__.
| 5862 | return _div_nearest(f_log_ten + log_d, 100) |
| 5863 | |
| 5864 | class _Log10Memoize(object): |
| 5865 | """Class to compute, store, and allow retrieval of, digits of the |
| 5866 | constant log(10) = 2.302585.... This constant is needed by |
| 5867 | Decimal.ln, Decimal.log10, Decimal.exp and Decimal.__pow__.""" |
| 5868 | def __init__(self): |
| 5869 | self.digits = "23025850929940456840179914546843642076011014886" |
| 5870 | |
| 5871 | def getdigits(self, p): |
| 5872 | """Given an integer p >= 0, return floor(10**p)*log(10). |
| 5873 | |
| 5874 | For example, self.getdigits(3) returns 2302. |
| 5875 | """ |
| 5876 | # digits are stored as a string, for quick conversion to |
| 5877 | # integer in the case that we've already computed enough |
| 5878 | # digits; the stored digits should always be correct |
| 5879 | # (truncated, not rounded to nearest). |
| 5880 | if p < 0: |
| 5881 | raise ValueError("p should be nonnegative") |
| 5882 | |
| 5883 | if p >= len(self.digits): |
| 5884 | # compute p+3, p+6, p+9, ... digits; continue until at |
| 5885 | # least one of the extra digits is nonzero |
| 5886 | extra = 3 |
| 5887 | while True: |
| 5888 | # compute p+extra digits, correct to within 1ulp |
| 5889 | M = 10**(p+extra+2) |
| 5890 | digits = str(_div_nearest(_ilog(10*M, M), 100)) |
| 5891 | if digits[-extra:] != '0'*extra: |
| 5892 | break |
| 5893 | extra += 3 |
| 5894 | # keep all reliable digits so far; remove trailing zeros |
| 5895 | # and next nonzero digit |
| 5896 | self.digits = digits.rstrip('0')[:-1] |
| 5897 | return int(self.digits[:p+1]) |
| 5898 | |
| 5899 | _log10_digits = _Log10Memoize().getdigits |
| 5900 |