提问人:no comment 提问时间:9/15/2021 最后编辑:Olivierno comment 更新时间:10/14/2021 访问量:362
我们可以从很少的浮动中获得多少不同的金额?
How many different sums can we get from very few floats?
问:
有人只是问为什么与.很快被骗到浮点数学坏了吗?并删除了。sum(myfloats)
sum(reversed(myfloats))
但这让我很好奇:仅仅通过按不同的顺序将它们相加,我们就能从很少的浮点数中得到多少不同的总和?使用三个浮点数,我们可以得到三个不同的总和:
>>> from itertools import permutations
>>> for perm in permutations([0.2, 0.3, 0.4]):
print(perm, sum(perm))
(0.2, 0.3, 0.4) 0.9
(0.2, 0.4, 0.3) 0.9000000000000001
(0.3, 0.2, 0.4) 0.9
(0.3, 0.4, 0.2) 0.8999999999999999
(0.4, 0.2, 0.3) 0.9000000000000001
(0.4, 0.3, 0.2) 0.8999999999999999
我相信加法对于浮点数是可交换的(即)。对于第一对加法,我们有三个选择,然后对于第二对加法,我们有一个“选择”,所以三个总和是我们只用三个值就能得到的最多。a + b == b + a
我们可以用四个值得到三个以上的不同总和吗?通过一些实验,我没有发现这种情况。如果我们做不到:为什么不呢?如果可以的话:有多少?有多少人有五个?
正如埃里克刚才指出的那样,对于三个以上的值,除了从左到右求和之外,还有不同的可能性,例如。我对任何添加数字的方式都感兴趣。(a+b) + (c+d)
请注意,我说的是 64 位浮点数(我是 Python 人,我知道在其他语言中它们通常被称为双精度)。
答:
你当然可以。对于您的具体问题:
我们可以用四个值得到三个以上的不同总和吗?
下面是一组值,表明情况确实如此:
v0 = -1.5426605224883486e63
v1 = 7.199082438280276e62
v2 = 8.227522786603223e62
v3 = -1.4272476927059597e45
print (v0 + v2 + v1 + v3)
print (v3 + v1 + v0 + v2)
print (v2 + v1 + v0 + v3)
print (v1 + v2 + v3 + v0)
当我运行它时,我得到:
1.36873053731e+48
1.370157785e+48
1.46007438964e+48
1.46150163733e+48
所有这些都是不同的。
对于 5,下面是一个示例集:
v0 = -8.016918059381093e-292
v1 = -0.0
v2 = 2.4463434328110855e-296
v3 = 8.016673425037811e-292
v4 = 1.73833895195875e-310
print(v4 + v1 + v0 + v2 + v3)
print(v2 + v3 + v0 + v1 + v4)
print(v4 + v3 + v1 + v0 + v2)
print(v1 + v0 + v2 + v3 + v4)
print(v1 + v4 + v2 + v0 + v3)
这将打印:
-8.90029543403e-308
1.73833895196e-310
-4.45041933248e-308
-8.88291204451e-308
0.0
同样,有所有不同的结果。
如果你能找到任何足够大的 n 的值(也许 n>2 就足够了),这样所有不同的排列都会产生不同的总和,我不会感到惊讶;取模那些由于交换性而等效的模。(当然,这只是一个猜想。通过灾难性的取消,您可以安排结果有很大差异。n
评论
n
n
If you have N floats you have N! possible sequences how to add them. Assuming you always do one addition at a time this leads to 0.5[N*(N-1)]*(N-2)! versions of the calculation. (assuming a+b=b+a for the first pair and a+b has the same rounding as b+a). After each step there is a rounding error. As long as you dont force the calculation sequence I would expect N!/2 possible results due to rounding errors. The differences however should be in the lowest significant digits as long as you work with pure positive numbers.
If you do things like substracting very similar numbers (example:9999999.9+(-9999999.8) the rounding errors can become critcal however (depending on the size of your floats).
Using brackets you can get even more combinations (Example: (a+b)+(c+d) may differ from ((a+b)+c)+d because you force a rounding with each pair of brackets.
评论