Returns the natural (base e) logarithm of self.
(self, context=None)
| 3155 | |
| 3156 | |
| 3157 | def ln(self, context=None): |
| 3158 | """Returns the natural (base e) logarithm of self.""" |
| 3159 | |
| 3160 | if context is None: |
| 3161 | context = getcontext() |
| 3162 | |
| 3163 | # ln(NaN) = NaN |
| 3164 | ans = self._check_nans(context=context) |
| 3165 | if ans: |
| 3166 | return ans |
| 3167 | |
| 3168 | # ln(0.0) == -Infinity |
| 3169 | if not self: |
| 3170 | return _NegativeInfinity |
| 3171 | |
| 3172 | # ln(Infinity) = Infinity |
| 3173 | if self._isinfinity() == 1: |
| 3174 | return _Infinity |
| 3175 | |
| 3176 | # ln(1.0) == 0.0 |
| 3177 | if self == _One: |
| 3178 | return _Zero |
| 3179 | |
| 3180 | # ln(negative) raises InvalidOperation |
| 3181 | if self._sign == 1: |
| 3182 | return context._raise_error(InvalidOperation, |
| 3183 | 'ln of a negative value') |
| 3184 | |
| 3185 | # result is irrational, so necessarily inexact |
| 3186 | op = _WorkRep(self) |
| 3187 | c, e = op.int, op.exp |
| 3188 | p = context.prec |
| 3189 | |
| 3190 | # correctly rounded result: repeatedly increase precision by 3 |
| 3191 | # until we get an unambiguously roundable result |
| 3192 | places = p - self._ln_exp_bound() + 2 # at least p+3 places |
| 3193 | while True: |
| 3194 | coeff = _dlog(c, e, places) |
| 3195 | # assert len(str(abs(coeff)))-p >= 1 |
| 3196 | if coeff % (5*10**(len(str(abs(coeff)))-p-1)): |
| 3197 | break |
| 3198 | places += 3 |
| 3199 | ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) |
| 3200 | |
| 3201 | context = context._shallow_copy() |
| 3202 | rounding = context._set_rounding(ROUND_HALF_EVEN) |
| 3203 | ans = ans._fix(context) |
| 3204 | context.rounding = rounding |
| 3205 | return ans |
| 3206 | |
| 3207 | def _log10_exp_bound(self): |
| 3208 | """Compute a lower bound for the adjusted exponent of self.log10(). |