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
decimal sqrt method doesn't use round-half-even #44997
Comments
According to version 1.66 of Cowlishaw's `General Decimal Arithmetic >>> from decimal import *
>>> getcontext().prec = 6
>>> Decimal(9123455**2).sqrt()
Decimal("9.12345E+6") The exact value of this square root is exactly halfway between two Decimal("9.12346E+6") This bug only seems to occur when the number of significant digits in It seems to me that this is a minor bug that will occur rarely and is |
Doesn't the spec also require that /inputs/ get rounded to working precision /before/ operations are performed? If so, the exact square 83237431137025 is rounded down to 83237400000000, and sqrt(83237400000000) is 9.12345E+6 rounded to 6 digits. |
I don't think inputs should be rounded; note 1 near the start of the `Arithmetic Operations' section of the specification says: "Operands may have more than precision digits and are not rounded before use." |
Some more strange results for sqrt(): with Emax = 9, Emin = -9 and prec = 3:
>>> Decimal("9.998E-19").sqrt()
Decimal("1.00E-9")
>>> getcontext()
Context(prec=3, rounding=ROUND_HALF_EVEN, Emin=-9, Emax=9, capitals=1, flags=[Rounded, Inexact], traps=[DivisionByZero, Overflow, InvalidOperation])
>>> Decimal("1.12E-19").sqrt()
Decimal("3.4E-10") (The true value of the square root is 3.34664...e-10, which should surely be rounded to 3.3E-10, not 3.4E-10?).
>>> Decimal("4.21E-20").sqrt()
Decimal("2.0E-10") The answer should, I think, be 2.1E-10; here the reference implementation also gives 2.1E-10.
>>> Decimal("1.01001").sqrt()
Decimal("1.01") Shouldn't this be 1.00? But again Python agrees with the reference implementation. Either all this is pretty mixed up, or I'm fundamentally misunderstanding things. I have a patch that I think fixes all these bugs; if there's any agreement that they really are bugs then I'll post it. Can anyone shed any light on the above results? |
One more result. This is definitely getting suspicious now--I'll submit my patch. >>> from decimal import *
>>> getcontext().prec = 3
>>> Decimal(11772).sqrt()
Decimal("109")
>>> Decimal(11774).sqrt()
Decimal("108") |
Of course you're right, the spec does say inputs shouldn't be rounded. And that last example is horrendous: sqrt should definitely be monotonic (a floating function f is "monotonic" if it guarantees f(x) >= f(y) whenever x >= y; you found x and y such that x > y but sqrt(x) < sqrt(y) -- ouch!). |
See patch 1741308. I'll contact Mike Cowlishaw to verify that the reference implementation really is buggy. |
Fixed in the revisions 56654 to 56656, in the decimal-branch, using patches generated by Mark, thanks! |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: