Returns the natural (base e) logarithm of self.
(self, context=None)
| 3200 | |
| 3201 | |
| 3202 | def ln(self, context=None): |
| 3203 | """Returns the natural (base e) logarithm of self.""" |
| 3204 | |
| 3205 | if context is None: |
| 3206 | context = getcontext() |
| 3207 | |
| 3208 | # ln(NaN) = NaN |
| 3209 | ans = self._check_nans(context=context) |
| 3210 | if ans: |
| 3211 | return ans |
| 3212 | |
| 3213 | # ln(0.0) == -Infinity |
| 3214 | if not self: |
| 3215 | return _NegativeInfinity |
| 3216 | |
| 3217 | # ln(Infinity) = Infinity |
| 3218 | if self._isinfinity() == 1: |
| 3219 | return _Infinity |
| 3220 | |
| 3221 | # ln(1.0) == 0.0 |
| 3222 | if self == _One: |
| 3223 | return _Zero |
| 3224 | |
| 3225 | # ln(negative) raises InvalidOperation |
| 3226 | if self._sign == 1: |
| 3227 | return context._raise_error(InvalidOperation, |
| 3228 | 'ln of a negative value') |
| 3229 | |
| 3230 | # result is irrational, so necessarily inexact |
| 3231 | op = _WorkRep(self) |
| 3232 | c, e = op.int, op.exp |
| 3233 | p = context.prec |
| 3234 | |
| 3235 | # correctly rounded result: repeatedly increase precision by 3 |
| 3236 | # until we get an unambiguously roundable result |
| 3237 | places = p - self._ln_exp_bound() + 2 # at least p+3 places |
| 3238 | while True: |
| 3239 | coeff = _dlog(c, e, places) |
| 3240 | # assert len(str(abs(coeff)))-p >= 1 |
| 3241 | if coeff % (5*10**(len(str(abs(coeff)))-p-1)): |
| 3242 | break |
| 3243 | places += 3 |
| 3244 | ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) |
| 3245 | |
| 3246 | context = context._shallow_copy() |
| 3247 | rounding = context._set_rounding(ROUND_HALF_EVEN) |
| 3248 | ans = ans._fix(context) |
| 3249 | context.rounding = rounding |
| 3250 | return ans |
| 3251 | |
| 3252 | def _log10_exp_bound(self): |
| 3253 | """Compute a lower bound for the adjusted exponent of self.log10(). |
no test coverage detected