diff --git a/mathics/format/box/numberform.py b/mathics/format/box/numberform.py
index fb56184b2..6e916e13d 100644
--- a/mathics/format/box/numberform.py
+++ b/mathics/format/box/numberform.py
@@ -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:
@@ -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):
@@ -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)
@@ -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.")
diff --git a/test/builtin/atomic/test_numbers.py b/test/builtin/atomic/test_numbers.py
index 0b66c9d0b..f711f1d23 100644
--- a/test/builtin/atomic/test_numbers.py
+++ b/test/builtin/atomic/test_numbers.py
@@ -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"),
[
diff --git a/test/format/format_tests.yaml b/test/format/format_tests.yaml
index f6bf8a2a9..bc9d094b6 100644
--- a/test/format/format_tests.yaml
+++ b/test/format/format_tests.yaml
@@ -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: -4.33
+ System`InputForm: -4.326563712
System`OutputForm: -4.3
System`StandardForm: "\n -\n 4.33\n"
System`TraditionalForm: "\n -\n 4.33\n"
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.