-
-
Notifications
You must be signed in to change notification settings - Fork 33.1k
Description
Bug report
Bug description:
The decimal.Decimal class is inconsistent when handling very large integers, over 29. Mathematical operations that should be equivalent (like Decimal(-v) and -Decimal(v)) produce different results, with some operations unexpectedly switching to scientific notation and losing precision.
This breaks mathematical consistency and can cause silent precision loss in applications that process large numbers, particularly financial, scientific, or cryptographic applications where precision is critical.
Steps to Reproduce:
from decimal import Decimal
# Bug occurs with integers having 29+ digits
v = 98765432109876543210987654321
# These should be equal but aren't (and does work as expected with smaller values):
result1 = Decimal(-v) # Full precision: -98765432109876543210987654321
result2 = -Decimal(v) # Scientific notation: -9.876543210987654321098765432E+28
assert result1 == result2 # This fails!
# abs() is also affected:
large_negative = Decimal('-98765432109876543210987654321')
assert abs(large_negative) == Decimal('98765432109876543210987654321') # This fails too!
Expected Result: Both expressions should produce identical Decimal values with full precision preserved.
Actual Result: One method preserves full precision while the other switches to scientific notation, causing mathematically equivalent expressions to be unequal.
Additional Information:
- Affects Python 3.12.3 (and likely other versions)
- Threshold is exactly 29 digits
- Works correctly for numbers with 28 digits or fewer
- Affects abs(), negation, and potentially other arithmetic operations
- Can cause silent precision loss in calculations
CPython versions tested on:
3.12
Operating systems tested on:
Windows