Issue
I am using Decimal with strings to avoid the typical problem
I have two dictionaries that have the same keys and values but with the keys in a different order. The sum of the values of these dictionaries should be zero. However, it is not zero when I sum them in a certain order.
These are my dictionaries and the comparisons I made to make sure the values are the same:
a = {'key_A': Decimal('0'),
'key_B': Decimal('-1002708'),
'key_C': Decimal('3965.5752'),
'key_D': Decimal('991393.8'),
'key_E': Decimal('-991393.8'),
'key_F': Decimal('1173.30984201680672268907563'),
'key_G': Decimal('-7348.6248'),
'key_H': Decimal('6175.31495798319327731092437'),
'key_I': Decimal('-741'),
'key_J': Decimal('0'),
'key_K': Decimal('4641'),
'key_U': Decimal('-3900'),
'key_L': Decimal('1038000'),
'key_M': Decimal('0'),
'key_N': Decimal('0'),
'key_O': Decimal('0'),
'key_P': Decimal('-3965.5752'),
'key_Q': Decimal('0'),
'key_R': Decimal('0'),
'key_S': Decimal('-15570'),
'key_T': Decimal('-19722')}
b = {'key_C': Decimal('3965.5752'),
'key_D': Decimal('991393.8'),
'key_B': Decimal('-1002708'),
'key_K': Decimal('4641'),
'key_U': Decimal('-3900'),
'key_J': Decimal('0'),
'key_A': Decimal('0'),
'key_G': Decimal('-7348.6248'),
'key_H': Decimal('6175.31495798319327731092437'),
'key_I': Decimal('-741'),
'key_R': Decimal('0'),
'key_N': Decimal('0'),
'key_T': Decimal('-19722'),
'key_P': Decimal('-3965.5752'),
'key_M': Decimal('0'),
'key_L': Decimal('1038000'),
'key_F': Decimal('1173.30984201680672268907563'),
'key_O': Decimal('0'),
'key_Q': Decimal('0'),
'key_E': Decimal('-991393.8'),
'key_S': Decimal('-15570')}
print(sorted(list(a.keys()))==sorted(list(b.keys()))) # "True" so the keys are the same
print(len(a), len(b)) # "21 21" the length are the same
keys = sorted(list(a.keys()))
for k in keys:
assert a[k]==b[k] # never throws exception so the values are the same
sum_d = lambda d: sum(d[key] for key in d) # a function that sums all the values in a dictionary
HERE IS THE PROBLEM:
print(sum_d(a), sum_d(b)) # "4E-22 0E-21" EVEN WHEN THE VALUES ARE THE SAME THE SUMS ARE NOT WTF
HERE IS WHEN IT GETS EVEN WEIRDER I wanted to make sure this was because of the order, so I inverted the order
a_new = {key:a[key] for key in b.keys()}
b_new = {key:b[key] for key in a.keys()}
print(sum_d(a_new), sum_d(b_new)) # "0E-21 4E-22" THE VALUES INVERTED SO IT IS BECAUSE OF THE ORDER
So my question is just..... WHY... why python sum is not commutative?
Solution
In general, floating-point arithmetic is not commutative. The Decimal
class is floating-point.
The default precision for arithmetic operations with Decimal
is 28 digits. You can change this by altering the context. For example, increase the precision to 40 digits with the following code:
import decimal
decimal.getcontext().prec = 40
If you want to raise an exception for inexact arithmetic, you can configure this explicitly. You might set up the context explicitly, for example:
decimal.setcontext(decimal.Context(
traps=[decimal.Inexact],
))
Answered By - Dietrich Epp Answer Checked By - Robin (PHPFixing Admin)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.