diff --git a/mpmath/ctx_mp_python.py b/mpmath/ctx_mp_python.py index 11cc5979..4f452f23 100644 --- a/mpmath/ctx_mp_python.py +++ b/mpmath/ctx_mp_python.py @@ -356,7 +356,8 @@ class _mpf(mpnumeric): return t ** s def __format__(s, format_spec): - return format_mpf(s._mpf_, format_spec) + _, _, (prec, _) = s._ctxdata + return format_mpf(s._mpf_, format_spec, prec) def sqrt(s): return s.context.sqrt(s) diff --git a/mpmath/libmp/libmpf.py b/mpmath/libmp/libmpf.py index f5280d6b..8f5afc4b 100644 --- a/mpmath/libmp/libmpf.py +++ b/mpmath/libmp/libmpf.py @@ -1397,7 +1397,7 @@ _FLOAT_FORMAT_SPECIFICATION_MATCHER = re.compile(r""" (?P[,_])? (?:\.(?P0|[1-9][0-9]*))? (?P[UDYZN])? - (?P[eEfFgG])? + (?P[eEfFgG%])? """, re.DOTALL | re.VERBOSE).fullmatch _GMPY_ROUND_CHAR_DICT = { @@ -1488,6 +1488,8 @@ def format_fixed(s, base=10, alternate=False, no_neg_0=False, + percent=False, + prec=0, rounding=round_nearest): ''' Format a number into fixed point. @@ -1496,6 +1498,9 @@ def format_fixed(s, Does not perform padding or aligning ''' + if percent: + s = mpf_mul(s, from_int(100), prec=prec, rnd=round_nearest) + # First, get the exponent to know how many digits we will need _, _, exponent = to_digits_exp(s, 1, base) @@ -1568,6 +1573,9 @@ def format_fixed(s, if digits[-1] == "." and strip_last_zero: digits = digits[:-1] + if percent: + digits = digits + '%' + return sign, digits @@ -1608,7 +1616,7 @@ def format_scientific(s, return sign, digits + sep + f'{exponent:+03d}' -def format_mpf(num, format_spec): +def format_mpf(num, format_spec, prec): format_dict = read_format_spec(format_spec) capitalize = False @@ -1616,6 +1624,11 @@ def format_mpf(num, format_spec): capitalize = True fmt_type = format_dict['type'].lower() + percent = False + if fmt_type == '%': + percent = True + fmt_type = 'f' + precision = format_dict['precision'] digits = '' @@ -1664,6 +1677,8 @@ def format_mpf(num, format_spec): base=10, alternate=format_dict['alternate'], no_neg_0=format_dict['no_neg_0'], + percent=percent, + prec=prec, rounding=rounding ) else: # The format type is scientific diff --git a/mpmath/tests/test_format.py b/mpmath/tests/test_format.py index e1d2fb6b..6d2e4771 100644 --- a/mpmath/tests/test_format.py +++ b/mpmath/tests/test_format.py @@ -63,7 +63,7 @@ def random_fmt(): fmt_str += '.' + str(random.randint(1, 40)) # Type - fmt_str += random.choice('fFgGeE') + fmt_str += random.choice('fFgGeE%') fmt_str += '}' return fmt_str