Fix new-style formatting without type specifier (repr_dps vs dps)
Closes #943
This commit is contained in:
+4
-1
@@ -221,7 +221,10 @@ Setting the ``mp.pretty`` option will use the ``str()``-style output for ``repr(
|
||||
>>> mpf(0.6)
|
||||
mpf('0.59999999999999998')
|
||||
|
||||
To use enough digits to be able recreate value exactly, set ``mp.pretty_dps`` to ``"repr"``.
|
||||
To use enough digits to be able recreate value exactly, set ``mp.pretty_dps``
|
||||
to ``"repr"`` (default value is ``"str"``). Same option is used to control
|
||||
default number of digits in the new-style string formatting *without format
|
||||
specifier*, i.e. `format(exp(mpf(1)))`.
|
||||
|
||||
The number of digits with which numbers are printed by default is determined by
|
||||
the working precision. To specify the number of digits to show without
|
||||
|
||||
@@ -427,7 +427,8 @@ class _mpf(mpnumeric):
|
||||
"""
|
||||
|
||||
_, _, (prec, _) = s._ctxdata
|
||||
return format_mpf(s._mpf_, format_spec, prec)
|
||||
ctx = s.context
|
||||
return format_mpf(s._mpf_, format_spec, prec, ctx._pretty_repr_dps)
|
||||
|
||||
def sqrt(s):
|
||||
return s.context.sqrt(s)
|
||||
@@ -695,7 +696,8 @@ class _mpc(mpnumeric):
|
||||
"""
|
||||
|
||||
_, _, (prec, _) = s._ctxdata
|
||||
return format_mpc(s._mpc_, format_spec, prec)
|
||||
ctx = s.context
|
||||
return format_mpc(s._mpc_, format_spec, prec, ctx._pretty_repr_dps)
|
||||
|
||||
|
||||
complex_types = (complex, _mpc)
|
||||
|
||||
@@ -1601,7 +1601,7 @@ def fill_sep(digits, sep, prev, nmod, sep_range):
|
||||
for pos in range(nmod, len(digits), sep_range))
|
||||
|
||||
|
||||
def format_digits(num, format_dict, prec):
|
||||
def format_digits(num, format_dict, prec, _pretty_repr_dps):
|
||||
capitalize = False
|
||||
if format_dict['type'] in list('AFGE'):
|
||||
capitalize = True
|
||||
@@ -1633,7 +1633,7 @@ def format_digits(num, format_dict, prec):
|
||||
strip_last_zero = True
|
||||
|
||||
if precision < 0:
|
||||
precision = repr_dps(prec)
|
||||
precision = repr_dps(prec) if _pretty_repr_dps else prec_to_dps(prec)
|
||||
if precision == 0:
|
||||
precision = 1
|
||||
|
||||
@@ -1741,9 +1741,9 @@ def format_digits(num, format_dict, prec):
|
||||
return sign, int_part + digits
|
||||
|
||||
|
||||
def format_mpf(num, format_spec, prec):
|
||||
def format_mpf(num, format_spec, prec, _pretty_repr_dps):
|
||||
format_dict = read_format_spec(format_spec)
|
||||
sign, digits = format_digits(num, format_dict, prec)
|
||||
sign, digits = format_digits(num, format_dict, prec, _pretty_repr_dps)
|
||||
nchars = len(digits) + len(sign)
|
||||
lpad, rpad = calc_padding(
|
||||
nchars, format_dict['width'], format_dict['align'])
|
||||
@@ -1756,7 +1756,7 @@ def format_mpf(num, format_spec, prec):
|
||||
+ rpad*format_dict['fill_char']
|
||||
|
||||
|
||||
def format_mpc(num, format_spec, prec):
|
||||
def format_mpc(num, format_spec, prec, _pretty_repr_dps):
|
||||
format_dict = read_format_spec(format_spec)
|
||||
|
||||
if format_dict['fill_char'] == '0':
|
||||
@@ -1772,10 +1772,10 @@ def format_mpc(num, format_spec, prec):
|
||||
fmt_type = format_dict['type'].lower()
|
||||
if not fmt_type:
|
||||
format_dict['type'] = 'g'
|
||||
sign_re, digits_re = format_digits(num[0], format_dict, prec)
|
||||
sign_re, digits_re = format_digits(num[0], format_dict, prec, _pretty_repr_dps)
|
||||
fmt_sign = format_dict['sign']
|
||||
format_dict['sign'] = '+'
|
||||
sign_im, digits_im = format_digits(num[1], format_dict, prec)
|
||||
sign_im, digits_im = format_digits(num[1], format_dict, prec, _pretty_repr_dps)
|
||||
digits_im += 'j'
|
||||
|
||||
if not fmt_type:
|
||||
|
||||
@@ -469,6 +469,10 @@ def test_mpf_fmt_cpython():
|
||||
# No formatting code.
|
||||
|
||||
assert f'{mp.mpf(0.0):.0}' == '0e+00'
|
||||
mp.pretty_dps = 'repr'
|
||||
assert f'{mp.pi}' == '3.1415926535897931'
|
||||
mp.pretty_dps = 'str'
|
||||
assert f'{mp.pi}' == '3.14159265358979'
|
||||
|
||||
|
||||
@settings(max_examples=20000)
|
||||
@@ -489,10 +493,12 @@ def test_mpf_floats_bulk(fmt, x):
|
||||
the same results for default precision.
|
||||
'''
|
||||
|
||||
mp.pretty_dps = "repr"
|
||||
if not x and math.copysign(1, x) == -1:
|
||||
return # skip negative zero
|
||||
spec = read_format_spec(fmt)
|
||||
if spec['frac_separators'] and vinfo < (3, 14):
|
||||
mp.pretty_dps = "str"
|
||||
return # see also python/cpython#130860
|
||||
if not spec['type'] and spec['precision'] < 0 and math.isfinite(x):
|
||||
# The mpmath could choose a different decimal
|
||||
@@ -503,6 +509,7 @@ def test_mpf_floats_bulk(fmt, x):
|
||||
if spec['type'] == '%' and math.isinf(100*x):
|
||||
return # mpf can't overflow
|
||||
assert format(x, fmt) == format(mp.mpf(x), fmt)
|
||||
mp.pretty_dps = "str"
|
||||
|
||||
|
||||
@settings(max_examples=20000)
|
||||
@@ -511,8 +518,10 @@ def test_mpf_floats_bulk(fmt, x):
|
||||
allow_infinity=True,
|
||||
allow_subnormal=True))
|
||||
def test_mpc_complexes(fmt, z):
|
||||
mp.pretty_dps = "repr"
|
||||
if ((not z.real and math.copysign(1, z.real) == -1)
|
||||
or (not z.imag and math.copysign(1, z.imag) == -1)):
|
||||
mp.pretty_dps = "str"
|
||||
return # skip negative zero
|
||||
spec = read_format_spec(fmt)
|
||||
if spec['frac_separators'] and vinfo < (3, 14):
|
||||
@@ -527,6 +536,7 @@ def test_mpc_complexes(fmt, z):
|
||||
assert complex(format(z)) == complex(format(mp.mpc(z)))
|
||||
else:
|
||||
assert format(z, fmt) == format(mp.mpc(z), fmt)
|
||||
mp.pretty_dps = "str"
|
||||
|
||||
|
||||
def test_mpc_fmt():
|
||||
|
||||
Reference in New Issue
Block a user