Use context's rounding mode per default in the format()

This commit is contained in:
Sergey B Kirpichev
2025-06-08 18:27:16 +03:00
parent e8bc7ea1a8
commit bad54feab6
4 changed files with 25 additions and 14 deletions
+2 -2
View File
@@ -33,8 +33,8 @@ Features:
* Implement mpf.__format__(), see #819, #831, #850, #859, #857, #862, #881,
#944 and #966 (Javier Garcia, Sergey B Kirpichev)
* Support conversion from scalar ndarray's, see #821 (Sergey B Kirpichev)
* Support rounding modes in mpf.__format__, see #823, #831 and #834 (Javier
Garcia, Sergey B Kirpichev)
* Support rounding modes in mpf.__format__, see #823, #831, #834
and #969 (Javier Garcia, Sergey B Kirpichev)
* Support '%' presentation type for mpf, see #847 (Sergey B Kirpichev)
* Support gmpy2-like rounding modes in to_str(), see #830 (Javier Garcia)
* Implement 'a'/'A' formating types for mpf.__format__, see #841 and #870
+6 -4
View File
@@ -396,6 +396,8 @@ class _mpf(mpnumeric):
* ``'Z'``: rounding towards zero
* ``'N'``: rounding to nearest (default)
If it's not specified, the context's rounding mode is used.
The rounding option must be set right before the presentation type:
>>> x = mp.mpf('-1.2345678')
@@ -428,9 +430,9 @@ class _mpf(mpnumeric):
"""
_, _, (prec, _) = s._ctxdata
_, _, (prec, rounding) = s._ctxdata
ctx = s.context
return format_mpf(s._mpf_, format_spec, prec, ctx._pretty_repr_dps)
return format_mpf(s._mpf_, format_spec, prec, rounding, ctx._pretty_repr_dps)
def sqrt(s):
return s.context.sqrt(s)
@@ -701,9 +703,9 @@ class _mpc(mpnumeric):
"""
_, _, (prec, _) = s._ctxdata
_, _, (prec, rounding) = s._ctxdata
ctx = s.context
return format_mpc(s._mpc_, format_spec, prec, ctx._pretty_repr_dps)
return format_mpc(s._mpc_, format_spec, prec, rounding, ctx._pretty_repr_dps)
complex_types = (complex, _mpc)
+7 -8
View File
@@ -1452,7 +1452,6 @@ def read_format_spec(format_spec):
'frac_separators': '',
'width': -1,
'precision': -1,
'rounding': round_nearest,
'type': ''
}
@@ -1595,7 +1594,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, _pretty_repr_dps):
def format_digits(num, format_dict, prec, rnd, _pretty_repr_dps):
capitalize = False
if format_dict['type'] in list('AFGE'):
capitalize = True
@@ -1618,7 +1617,7 @@ def format_digits(num, format_dict, prec, _pretty_repr_dps):
strip_last_zero = False
strip_zeros = False
rnd = format_dict['rounding']
rnd = format_dict.get('rounding', rnd)
if not fmt_type or fmt_type == 'g':
if not format_dict['alternate']:
@@ -1729,9 +1728,9 @@ def format_digits(num, format_dict, prec, _pretty_repr_dps):
return sign, int_part + digits
def format_mpf(num, format_spec, prec, _pretty_repr_dps):
def format_mpf(num, format_spec, prec, rnd, _pretty_repr_dps):
format_dict = read_format_spec(format_spec)
sign, digits = format_digits(num, format_dict, prec, _pretty_repr_dps)
sign, digits = format_digits(num, format_dict, prec, rnd, _pretty_repr_dps)
nchars = len(digits) + len(sign)
lpad, rpad = calc_padding(
nchars, format_dict['width'], format_dict['align'])
@@ -1744,7 +1743,7 @@ def format_mpf(num, format_spec, prec, _pretty_repr_dps):
+ rpad*format_dict['fill_char']
def format_mpc(num, format_spec, prec, _pretty_repr_dps):
def format_mpc(num, format_spec, prec, rnd, _pretty_repr_dps):
format_dict = read_format_spec(format_spec)
if format_dict['fill_char'] == '0':
@@ -1760,10 +1759,10 @@ def format_mpc(num, format_spec, prec, _pretty_repr_dps):
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, _pretty_repr_dps)
sign_re, digits_re = format_digits(num[0], format_dict, prec, rnd, _pretty_repr_dps)
fmt_sign = format_dict['sign']
format_dict['sign'] = '+'
sign_im, digits_im = format_digits(num[1], format_dict, prec, _pretty_repr_dps)
sign_im, digits_im = format_digits(num[1], format_dict, prec, rnd, _pretty_repr_dps)
digits_im += 'j'
if not fmt_type:
+10
View File
@@ -806,6 +806,16 @@ def test_mpf_fmt():
assert f"{mp.mpf('-0.1'):=.4Df}" == "-0.1000"
def test_default_rounding():
x = mp.mpf(mp.pi)
assert f"{x:.3f}" == '3.142'
mp.rounding = 'd'
assert f"{x:.3f}" == '3.141'
mp.rounding = 'u'
assert f"{x:.3f}" == '3.142'
def test_issue_858():
for n in range(2, 15):
str_num = '0.' + (n)*'9'