Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions mathics/format/box/numberform.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,24 @@ def int_to_string_shorter_repr(
return value_str


def _stored_digits(extended: sympy.Float) -> tuple[str, int]:
"""
The shortest decimal string that reads back as ``extended``, and its
number of significant digits. As in WMA, InputForm shows these for a
number of low precision: 3.1415926535897932385`3.
"""
bits = extended._prec
with mpmath.workprec(bits):
value = extended._to_mpmath(bits)
for n in range(1, dps(bits) + 4):
s = mpmath.nstr(value, n)
if sympy.Float(s, precision=bits)._mpf_ == extended._mpf_:
break
return s, n


def real_to_tuple_info(
real: Real, digits: Optional[int]
real: Real, digits: Optional[int], stored: bool = False
) -> tuple[str, int, bool, int, int]:
"""
Convert ``real`` to a tuple representing that value. The tuple consists of:
Expand All @@ -180,7 +196,9 @@ def real_to_tuple_info(
* Updated value of digits, according to the number precision.
* the decimal precision.

If ``digits`` is None, we use the default precision.
If ``digits`` is None, we use the default precision. If ``stored`` is
True, a PrecisionReal that keeps more bits than its precision shows
all the digits it keeps.
"""
binary_precision = real.precision
if isinstance(real, PrecisionReal):
Expand All @@ -202,7 +220,10 @@ def real_to_tuple_info(
is_nonnegative = True
return s, exponent, is_nonnegative, digits, precision

if digits is None:
if stored and isinstance(real, PrecisionReal) and real._extended is not None:
s, digits = _stored_digits(real._extended)
value = real._extended
elif digits is None:
if real.is_machine_precision:
value = real.value
s = repr(value)
Expand Down Expand Up @@ -462,7 +483,11 @@ def numberform_to_boxes(
if digits_after_decimal_point is None:
is_int = True
elif isinstance(value, Real):
s, exp, is_nonnegative, digits, precision = real_to_tuple_info(value, digits)
# As in WMA, InputForm and FullForm show all the digits kept.
stored = digits is None and form in ("System`InputForm", "System`FullForm")
s, exp, is_nonnegative, digits, precision = real_to_tuple_info(
value, digits, stored
)
else:
raise ValueError("Expected Real or Integer.")

Expand Down
46 changes: 46 additions & 0 deletions test/builtin/atomic/test_numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,52 @@ def test_low_precision_storage(str_expr, str_expected, msg):
check_evaluation(str_expr, str_expected, failure_message=msg)


@pytest.mark.parametrize(
("str_expr", "str_expected", "msg"),
[
(
"ToString[3.1415926535897932385`3, InputForm]",
'"3.1415926535897932385`3."',
"InputForm shows the digits that are kept, not the precision",
),
(
"ToString[FullForm[3.1415926535897932385`3]]",
'"3.1415926535897932385`3."',
None,
),
(
"ToString[-3.1415926535897932385`3, InputForm]",
'"-3.1415926535897932385`3."',
None,
),
("ToString[3.1415926535897932385`3]", '"3.14"', "OutputForm: the precision"),
(
"StringTake[ToString[N[Pi, 20] + 0``3, InputForm], 22]",
'"3.1415926535897932385`"',
None,
),
(
"Precision[1.5`20 - ToExpression[ToString[1.4`2, InputForm]]]",
"0.853872",
"reading InputForm back gives the same kept value",
),
(
"ToExpression[ToString[#, InputForm]] === # &[N[1/3, 3]]",
"True",
None,
),
(
"Precision[1.5`20 - ToExpression[ToString[N[1/3, 3], InputForm]]]",
"Precision[1.5`20 - N[1/3, 3]]",
None,
),
],
)
def test_low_precision_input_form(str_expr, str_expected, msg):
"""Compared with WMA 15"""
check_evaluation(str_expr, str_expected, failure_message=msg)


@pytest.mark.parametrize(
("str_expr", "str_expected", "msg"),
[
Expand Down
6 changes: 3 additions & 3 deletions test/format/format_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -171,17 +171,17 @@
-4.326563712`2:
msg: A negative Real number
latex:
System`InputForm: '-4.33'
System`InputForm: '-4.326563712'
System`OutputForm: '\text{-4.3}'
System`StandardForm: '-4.33'
System`TraditionalForm: '-4.33'
mathml:
System`InputForm: <mn>-4.33</mn>
System`InputForm: <mn>-4.326563712</mn>
System`OutputForm: <mtext>-4.3</mtext>
System`StandardForm: "<mrow>\n <mn>-</mn>\n <mn>4.33</mn>\n</mrow>"
System`TraditionalForm: "<mrow>\n <mn>-</mn>\n <mn>4.33</mn>\n</mrow>"
text:
System`InputForm: -4.33`2.
System`InputForm: -4.326563712`2.
System`OutputForm: '-4.3'
System`StandardForm: -4.33`2.
System`TraditionalForm: -4.33`2.
Expand Down
Loading