为什么 Python 小数和不可交换(当我改变顺序时结果不同)
Why Python Decimal sum is not commutative (different result when I change the order)
我对字符串使用 Decimal 以避免典型问题
我有两个字典,它们具有相同的键和值,但键的顺序不同。 这些字典的值之和应该为零。但是,当我按一定顺序对它们求和时,它不是零。
这些是我的字典和我为确保值相同而进行的比较:
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
问题来了:
print(sum_d(a), sum_d(b)) # "4E-22 0E-21" EVEN WHEN THE VALUES ARE THE SAME THE SUMS ARE NOT WTF
这是它变得更奇怪的时候
我想确定这是因为顺序,所以我颠倒了顺序
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
所以我的问题只是..... 为什么... 为什么python 总和不可交换?
您在 b
中有两个“key_H”键。
去掉b
中的'key_H': Decimal('6175.31495798319327731092437'),
行后,求和结果是一样的
一般来说,浮点运算是不可交换的。 Decimal
class 是浮点数。
Decimal
算术运算的默认精度为 28 位。您可以通过更改上下文来更改此设置。例如,使用以下代码将精度提高到 40 位:
import decimal
decimal.getcontext().prec = 40
如果你想为不精确的算术抛出异常,你可以显式配置它。您可以显式设置上下文,例如:
decimal.setcontext(decimal.Context(
traps=[decimal.Inexact],
))
我对字符串使用 Decimal 以避免典型问题
我有两个字典,它们具有相同的键和值,但键的顺序不同。 这些字典的值之和应该为零。但是,当我按一定顺序对它们求和时,它不是零。
这些是我的字典和我为确保值相同而进行的比较:
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
问题来了:
print(sum_d(a), sum_d(b)) # "4E-22 0E-21" EVEN WHEN THE VALUES ARE THE SAME THE SUMS ARE NOT WTF
这是它变得更奇怪的时候 我想确定这是因为顺序,所以我颠倒了顺序
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
所以我的问题只是..... 为什么... 为什么python 总和不可交换?
您在 b
中有两个“key_H”键。
去掉b
中的'key_H': Decimal('6175.31495798319327731092437'),
行后,求和结果是一样的
一般来说,浮点运算是不可交换的。 Decimal
class 是浮点数。
Decimal
算术运算的默认精度为 28 位。您可以通过更改上下文来更改此设置。例如,使用以下代码将精度提高到 40 位:
import decimal
decimal.getcontext().prec = 40
如果你想为不精确的算术抛出异常,你可以显式配置它。您可以显式设置上下文,例如:
decimal.setcontext(decimal.Context(
traps=[decimal.Inexact],
))