为什么 a / (b*c) 在 Python 中比 a / b / c 慢(通常)?

Why is a / (b*c) slower than a / b / c in Python (and in general)?

我在为神经网络库编写一些数学导数函数时偶然发现了一个有趣的优化问题。事实证明,对于大值,表达式 a / (b*c)a / b / c 需要更长的计算时间(参见下面的 timeit)。但由于两个表达式相等:

提前致谢:)

In [2]: timeit.timeit('1293579283509136012369019234623462346423623462346342635610 / (52346234623632464236234624362436234612830128521357*32189512234623462637501237)')
Out[2]: 0.2646541080002862

In [3]: timeit.timeit('1293579283509136012369019234623462346423623462346342635610 / 52346234623632464236234624362436234612830128521357 / 32189512234623462637501237')
Out[3]: 0.008390166000026511

为什么 a/(b*c) 慢?

(b*c) 以无限精度将两个非常大的整数相乘。这是比执行浮点除法(精度有限)更昂贵的操作。

这两个计算是否等价?

在实践中,a/(b*c)a/b/c会给出不同的结果,因为浮点计算不准确,以不同的顺序进行运算会产生不同的结果。

例如:

a = 10 ** 33
b = 10000000000000002
c = 10 ** 17
print(a / b / c)    # 0.9999999999999999
print(a / (b * c))  # 0.9999999999999998

它归结为计算机deals如何使用它使用的数字。

为什么Python不将a/(b*c)计算为a/b/c

这会产生令人惊讶的结果。用户应该能够期望

d = b*c
a / d

应该与

有相同的结果
a / (b*c)

所以如果 a / (b*c) 给出了不同的结果,那将是非常神秘行为的来源,因为它被 a / b / c 神奇地取代了。