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