Reputation: 1
I was using Python's Decimal module to perform multiplication and division under the impression that it would be exact (a/b*b should return a). However, this is not the case.
from decimal import *
getcontext().prec = 50
dec1 = Decimal("703")
dec2 = Decimal("3499")
dec3 = dec1/dec2
print(dec3*dec2)
if dec1==dec3*dec2:
print(True)
else:
print(False)
The output I got is
702.99999999999999999999999999999999999999999999999
False
My question is is there any module or function to make this process more exact? I have code that require this relation (a/b*b ==a) to be true.
Upvotes: 0
Views: 244
Reputation: 350
When using real numbers, it is always recommended to not use ==
. The division leads to a real number which has a fixed memory (varies on the language), thus the division is always rounded off. Thereby causing the multiplication to give an approximate answer.
Instead you can use,
def check_equals(a, b, threshold=1e-6):
if abs(a-b)<threshold:
return True
return False
You can change the threshold to your liking.
Upvotes: 1
Reputation: 51037
The Decimal
class is meant for representing decimal numbers with a fixed number of decimal places. This means that most fractions will not be represented exactly, since they have infinite decimal expansions; for example, 1/3 = 0.333333333... will be rounded to a finite number of decimal places as a Decimal
.
If you need exact representations of rational numbers so that multiplication and division are true inverses, use the fractions module:
>>> from fractions import Fraction
>>> a = Fraction(703)
>>> b = Fraction(3499)
>>> c = a / b
>>> print(c)
703/3499
>>> print(c * b)
703
>>> a == c * b
True
>>> d = Fraction(1, 3)
>>> d * 3 == 1
True
Upvotes: 2
Reputation: 151
Consider not using that decimal module for the integers. Per the documentation, the decimal module retains significant figures, including zeros: https://docs.python.org/3/library/decimal.html. You should avoid applying this decimal module to your integers and fractions.
Upvotes: 0