Refactor round_digits()
* add exponent argument * pass original number * make inexact flag local
This commit is contained in:
+11
-21
@@ -1085,30 +1085,28 @@ def to_digits_exp(s, dps, base=10):
|
||||
exponent += len(digits) - fixdps - 1
|
||||
return sign, digits, exponent
|
||||
|
||||
def round_digits(sign, digits, dps, base, rnd=round_down, fixed=False,
|
||||
inexact=False):
|
||||
def round_digits(s, digits, exponent, dps, base, rnd=round_down, fixed=False):
|
||||
"""
|
||||
Returns the rounded digits, and the number of places the decimal point was
|
||||
shifted.
|
||||
|
||||
``inexact`` marks that the value has a nonzero remainder past the last
|
||||
supplied digit, so directed and nearest rounding round it up even when
|
||||
every extracted guard digit is zero.
|
||||
"""
|
||||
|
||||
assert len(digits) > dps
|
||||
assert rnd in (round_nearest, round_up, round_down, round_ceiling,
|
||||
round_floor)
|
||||
sign = s[0]
|
||||
|
||||
# to_digits_exp truncates; flag a nonzero remainder past the last digit so
|
||||
# rounding is not fooled by a short zero tail.
|
||||
inexact = s[2] + len(digits) - 1 - exponent < 0
|
||||
|
||||
if rnd == round_ceiling:
|
||||
rnd = round_down if sign else round_up
|
||||
elif rnd == round_floor:
|
||||
rnd = round_up if sign else round_down
|
||||
|
||||
exponent = 0
|
||||
|
||||
if rnd == round_down:
|
||||
return digits[:dps], 0
|
||||
return digits[:dps], exponent
|
||||
elif rnd == round_nearest:
|
||||
rnd_digs = stddigits[(base//2 + base % 2):base]
|
||||
else:
|
||||
@@ -1253,8 +1251,7 @@ def to_str(s, dps, strip_zeros=True, min_fixed=None, max_fixed=None,
|
||||
n = int(digits, 16) >> shift
|
||||
digits = hex(n)[2:]
|
||||
|
||||
digits, exp_add = round_digits(s[0], digits, dps, base, rnd)
|
||||
exponent += exp_add
|
||||
digits, exponent = round_digits(s, digits, exponent, dps, base, rnd)
|
||||
|
||||
# Prettify numbers close to unit magnitude
|
||||
if not binary_exp and min_fixed < exponent < max_fixed:
|
||||
@@ -1489,10 +1486,6 @@ def format_fixed(s, dps, rnd=round_down):
|
||||
# exponent by +- 1)
|
||||
_, digits, exponent = to_digits_exp(
|
||||
s, max(dps+exponent+4, int(s[3]/blog2_10)), base)
|
||||
# to_digits_exp truncates; flag a nonzero remainder past the last digit so
|
||||
# rounding is not fooled by a short zero tail (#1131).
|
||||
inexact = s[2] + len(digits) - 1 - exponent < 0
|
||||
orig_dps = dps
|
||||
dps += exponent + 1
|
||||
|
||||
if dps < 0:
|
||||
@@ -1502,8 +1495,7 @@ def format_fixed(s, dps, rnd=round_down):
|
||||
exponent -= dps
|
||||
dps = 0
|
||||
|
||||
digits, exp_add = round_digits(s[0], digits, dps, base, rnd, True, inexact)
|
||||
exponent += exp_add
|
||||
digits, exponent = round_digits(s, digits, exponent, dps, base, rnd, True)
|
||||
|
||||
# Here we prepend the corresponding 0s to the digits string, according
|
||||
# to the value of exponent
|
||||
@@ -1525,8 +1517,7 @@ def format_scientific(s, dps, rnd=round_down):
|
||||
_, digits, exponent = to_digits_exp(s, max(dps + 10,
|
||||
int(s[3]/blog2_10) + 10),
|
||||
base)
|
||||
digits, exp_add = round_digits(s[0], digits, dps, base, rnd)
|
||||
exponent += exp_add
|
||||
digits, exponent = round_digits(s, digits, exponent, dps, base, rnd)
|
||||
|
||||
return digits[0], digits[1:], f'e{exponent:+03d}'
|
||||
|
||||
@@ -1616,8 +1607,7 @@ def format_digits(num, format_dict, prec, rnd, _pretty_repr_dps):
|
||||
|
||||
_, tdigits, exp = to_digits_exp(num, max(53/blog2_10, dps), 10)
|
||||
if num[1]:
|
||||
_, exp_add = round_digits(num, tdigits, dps, 10, rnd)
|
||||
exp += exp_add
|
||||
_, exp = round_digits(num, tdigits, exp, dps, 10, rnd)
|
||||
|
||||
fix0 = 0 if fmt_type else 1
|
||||
if -4 <= exp < dps - fix0:
|
||||
|
||||
Reference in New Issue
Block a user