(c, e, p)
return _div_nearest(f_log_ten + log_d, 100)
Given integers c, e and p with c > 0, compute an integer
    approximation to 10**p * log(c*10**e), with an absolute error of
    at most 1.  Assumes that c*10**e is not exactly 1.
Given integers c, e and p with c > 0, compute an integer
    approximation to 10**p * log(c*10**e), with an absolute error of
    at most 1.  Assumes that c*10**e is not exactly 1.
Given integers c e and p with c > 0 compute an integer approximation to 10 ** p * log ( c * 10 ** e ) with an absolute error of at most 1 . Assumes that c * 10 ** e is not exactly 1 .
def _dlog(c, e, p):
    """Given integers c, e and p with c > 0, compute an integer
    approximation to 10**p * log(c*10**e), with an absolute error of
    at most 1.  Assumes that c*10**e is not exactly 1."""

    # Increase precision by 2. The precision increase is compensated
    # for at the end with a division by 100.
    p += 2

    # rewrite c*10**e as d*10**f with either f >= 0 and 1 <= d <= 10,
    # or f <= 0 and 0.1 <= d <= 1.  Then we can compute 10**p * log(c*10**e)
    # as 10**p * log(d) + 10**p*f * log(10).
    l = len(str(c))
    f = e+l - (e+l >= 1)

    # compute approximation to 10**p*log(d), with error < 27
    if p > 0:
        k = e+p-f
        if k >= 0:
            c *= 10**k
        else:
            c = _div_nearest(c, 10**-k)  # error of <= 0.5 in c

        # _ilog magnifies existing error in c by a factor of at most 10
        log_d = _ilog(c, 10**p) # error < 5 + 22 = 27
    else:
        # p <= 0: just approximate the whole thing by 0; error < 2.31
        log_d = 0

    # compute approximation to f*10**p*log(10), with error < 11.
    if f:
        extra = len(str(abs(f)))-1
        if p + extra >= 0:
            # error in f * _log10_digits(p+extra) < |f| * 1 = |f|
            # after division, error < |f|/10**extra + 0.5 < 10 + 0.5 < 11
            f_log_ten = _div_nearest(f*_log10_digits(p+extra), 10**extra)
        else:
            f_log_ten = 0
    else:
        f_log_ten = 0

    # error in sum < 11+27 = 38; error after division < 0.38 + 0.5 < 1
    return _div_nearest(f_log_ten + log_d, 100)
def _dlog ( c , e , p ) : # Increase precision by 2. The precision increase is compensated # for at the end with a division by 100. p += 2 # rewrite c*10**e as d*10**f with either f >= 0 and 1 <= d <= 10, # or f <= 0 and 0.1 <= d <= 1.  Then we can compute 10**p * log(c*10**e) # as 10**p * log(d) + 10**p*f * log(10). l = len ( str ( c ) ) f = e + l - ( e + l >= 1 ) # compute approximation to 10**p*log(d), with error < 27 if p > 0 : k = e + p - f if k >= 0 : c *= 10 ** k else : c = _div_nearest ( c , 10 ** - k ) # error of <= 0.5 in c # _ilog magnifies existing error in c by a factor of at most 10 log_d = _ilog ( c , 10 ** p ) # error < 5 + 22 = 27 else : # p <= 0: just approximate the whole thing by 0; error < 2.31 log_d = 0 # compute approximation to f*10**p*log(10), with error < 11. if f : extra = len ( str ( abs ( f ) ) ) - 1 if p + extra >= 0 : # error in f * _log10_digits(p+extra) < |f| * 1 = |f| # after division, error < |f|/10**extra + 0.5 < 10 + 0.5 < 11 f_log_ten = _div_nearest ( f * _log10_digits ( p + extra ) , 10 ** extra ) else : f_log_ten = 0 else : f_log_ten = 0 # error in sum < 11+27 = 38; error after division < 0.38 + 0.5 < 1 return _div_nearest ( f_log_ten + log_d , 100 )