Skip to content

Formatting rounding edge case #304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jagerber48 opened this issue Apr 21, 2025 · 1 comment
Open

Formatting rounding edge case #304

jagerber48 opened this issue Apr 21, 2025 · 1 comment

Comments

@jagerber48
Copy link
Contributor

I came across this formatting bug "in the wild":

from uncertainties import ufloat
from importlib import metadata
print(f'version : {metadata.version("uncertainties")}')
a = ufloat(9.994, 0.002)*1e-1
b = ufloat(9.997, 0.002)*1e-1
c = 1 - (1 - a) - (1-b)/2
print(f'1 : {c.n=}')
print(f'2 : {c.s=}')
print(f'3 : {c=}')
print(f'4 : {c=:.1u}')
print(f'5 : {c=:.1ue}')
version : 3.2.2
1 : c.n=0.9992500000000001
2 : c.s=0.00022360679774997898
3 : c=0.9992500000000001+/-0.00022360679774997898
4 : c=0.9993+/-0.0002
5 : c=(9.992+/-0.002)e-01

The discrepancy between line 4 and 5 is the bug. In one case the nominal value is rounded to 0.9993 and in another it is rounded to 9.992e-01. Based on the printout of the nominal value I would say case 4 has the right value.

This must be some bug that happens during the conversion to exponential format combine with floating point roundoff.

For what it's worth, sciform has what I consider to be the correct behavior on this example:

from sciform import SciNum
from importlib import metadata
print(f'version : {metadata.version("sciform")}')
sc = SciNum(c.n, c.s)
print(f'1 : {sc=:!1}')
print(f'2 : {sc=:!1e}')
version : 0.39.0
1 : sc=0.9993 ± 0.0002
2 : sc=(9.993 ± 0.002)e-01

sciform avoids these sorts of floating point rounding issues by immediately casting all inputs to Decimal and then working with that representation. Some thought was generally put into Decimal representation strategy and rounding. See this example.


Resolution to this issue depends on the route we choose to go at #192. If we choose to use sciform as the formatting backend then this issue will be resolved by that change. Otherwise someone (likely me as the resident formatting expert) would need to dig into what is going wrong and resolve it. Might be easy, might be a rabbit hole!

@newville
Copy link
Member

@jagerber48 My inclination is to do as little "fix formatting" here, with uncertainties, and rather a) move the existing formatting to a module where it can remain without much change or development, and b) work toward allowing other formatters, say with sciform.

Deferring to "registered user code" as pint would be OK, but I think sciform an optional dependency for "better formatting" would be preferable.

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

No branches or pull requests

2 participants