Skip to content

Plus, Times with an inexact zero: carry its accuracy, as in WMA - #2058

Merged
tombouctou merged 6 commits into
masterfrom
plus-times-inexact-zero
Oct 20, 2026
Merged

tombouctou merged 6 commits into
masterfrom
plus-times-inexact-zero

Conversation

@tombouctou

Copy link
Copy Markdown
Collaborator

A follow-up to #2050 (part of #2047). Independent of #2051 and the PRs on top of it: this one is against master.

Since #2050, a sum or product that held an inexact zero took the old path. A zero's "precision" is its accuracy, and that path read it as a precision. Now, as in WMA:

  • Plus: a zero adds its absolute error, 10^-accuracy, like any other term. A sum of zeros is a zero with the combined accuracy.
  • Times: a product with inexact zeros is a zero. Its accuracy is the sum of theirs, minus Log10 of the other factors.
  • Times: an exact 0 times arbitrary-precision numbers is an exact 0.
Input master this PR WMA 15
Precision[1.5`20 + 010]`` 10. 10.1761 10.1761
Precision[010 + 2]`` 10. 10.301 10.301
Precision[10^-10 + 030]`` 30. 20. 20.
Accuracy[010 + 020] 15. 10. 10.
Accuracy[1.5`20 - 1.5`20 + 030]`` 15. 19.5229 19.5229
Accuracy[1.5`20 * 010]`` 15. 9.82391 9.82391
Accuracy[010 * 020] 15. 30. 30.
0 * 1.5`20 0.`15.*^-15 0 0

Tests

test_inexact_zero_plus_times in test/builtin/atomic/test_numbers.py, with WMA 15 values. Full run on kimmy: doctests all pass. The pytest failures are the ones that depend on the order the tests run in; the failing files that touch numbers pass on their own.

🤖 Generated with Claude Code

A follow-up to #2050 (MATH-227).

- Plus: a PrecisionReal zero adds its absolute error, 10^-accuracy, as
  any other term does. Precision[1.5`20 + 0``10] is 10.1761 (was 10.),
  and a sum of zeros is a zero with the combined accuracy.
- Times: a product with PrecisionReal zeros is a zero whose accuracy is
  the sum of theirs, less Log10 of the other factors:
  Accuracy[1.5`20 * 0``10] is 9.82391 (was 15.).
- Times: an exact 0 times arbitrary-precision numbers is an exact 0, as
  in WMA (it gave 0.`15.*^-15).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tombouctou
tombouctou force-pushed the plus-times-inexact-zero branch from 18df81a to c93443e Compare October 19, 2026 21:21
Comment thread mathics/eval/numeric.py Outdated

def _exact_or_precision_reals(numbers: Tuple[Number, ...]) -> bool:
def _exact_or_precision_reals(
numbers: Tuple[Number, ...], allow_zeros: bool = False

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lowercase tuple please. And I guess it should be removed elsewhere in this file wherever it appears. Thanks.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 5d3395d: tuple[...] and list[...] throughout numeric.py, and the typing imports of Tuple and List are gone. The comments that named those types were updated too. mypy is clean on the file.

tombouctou added a commit to tombouctou/mathics-core that referenced this pull request Oct 19, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As asked in review, throughout the file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rocky

rocky commented Oct 19, 2026

Copy link
Copy Markdown
Member

@tombouctou

With the code in this PR, I see:

In[4]:= SetAccuracy[0, 20] * 1.5`20
Out[4]= 0.×10^-20

WMA 13 gives 0.10^-19. Is this correct?

Possible additional pytest:

@pytest.mark.parametrize(
    ("str_expr", "str_expected"),
    [
        # exact zeros that are syntactically different from the literal 0
        ("(1 - 1) * 1.5`20", "0"),
        ("(1/2 - 1/2) * 1.5`20", "0"),
        ("SetPrecision[0, Infinity] * 1.5`20", "0"),
       # whatever the right test is for above example.
    ],
)
def test_exact_zero_propagates_through_equivalent_zero_forms(str_expr, str_expected):
    """An exact zero that is constructed internally must still force an exact zero."""
    check_evaluation(str_expr, str_expected)    

SetAccuracy[0, 20] * 1.5`20 has accuracy 19.82 and is shown as
0.×10^-19, as in WMA. The exponent was taken from the rounded accuracy,
which gave 0.×10^-20. It is never positive, so a zero with a negative
accuracy shows as 0.

Also adds the exact-zero tests suggested in review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tombouctou

Copy link
Copy Markdown
Collaborator Author

Good catch — the value was right but the display was wrong. SetAccuracy[0, 20] * 1.520 has accuracy 19.8239, the same as in WMA (0``19.823908740944322). WMA shows an inexact zero as 0.×10^-Floor[accuracy]`, so that gives `0.×10^-19`. We took the exponent from the rounded accuracy and got `-20`. This bug was already on master and shows up for any zero whose accuracy is not a whole number.

Fixed in 9081be6 (mathics/format/box/numberform.py). The exponent is now -Floor[accuracy], and never positive, so 0``-2.3 shows as 0. as it does in WMA. Values compared with WMA 15:

Input before now WMA 15
0``20 0.×10^-20 0.×10^-20 0.×10^-20
0``20.5 0.×10^-20 0.×10^-20 0.×10^-20
0``19.5 0.×10^-20 0.×10^-19 0.×10^-19
SetAccuracy[0, 20] * 1.520` 0.×10^-20 0.×10^-19 0.×10^-19
0``-2.3 0.0 0. 0.

I added your suggested test test_exact_zero_propagates_through_equivalent_zero_forms (all three cases already gave 0), plus test_inexact_zero_output_form for the display.

Not changed here: zeros with a small accuracy (0``2.5 shows 0.00, WMA shows 0.), and the precision mark in InputForm (0.19.*^-19where WMA writes0``19.1`). Both behave the same as on master.

🤖 Generated with Claude Code

@mmatera mmatera left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

tombouctou and others added 2 commits October 20, 2026 15:01
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tombouctou
tombouctou merged commit 13a2ca6 into master Oct 20, 2026
15 checks passed
@tombouctou
tombouctou deleted the plus-times-inexact-zero branch October 20, 2026 11:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants