g0 = randn(1, 100);
g1 = g0;
g1(2:end) = flip(g1(2:end));
sprintf("%.15e", sum(g0) - sum(g1))
g0 = np.random.randn(100)
g1 = g0.copy()
g1[1:] = g1[1:][::-1]
print(sum(g0) - sum(g1))
在 Python 和 MATLAB 中,重新运行这些命令足够多次将重复以下值(或其负数;不完整列表):
8.881784197001252e-15
3.552713678800501e-15
2.6645352591003757e-15
4.440892098500626e-16
1.7763568394002505e-15
事实上,我第一次和第二次运行它们 - mat -> py -> mat -> py
- 它们完全相同,让我认为它们共享系统级别的 RNG 有延迟...(但忽略这个问题发生的情况)。
我会比这巧合更快地从地板上摔下来,而且还要跨越不同的语言。
发生了什么事?
Windows 11
、Python 3.11.4
、numpy 1.24.4
、MATLAB 9.14.0.2286388 (R2023a) 更新 3
,
最佳答案
您的值(value)观:
8.881784197001252e-15
3.552713678800501e-15
2.6645352591003757e-15
4.440892098500626e-16
1.7763568394002505e-15
匹配
>> [40,16,12,2,8].' * eps
ans =
1.0e-14 *
0.888178419700125
0.355271367880050
0.266453525910038
0.044408920985006
0.177635683940025
完全可以预料到您会得到此范围内的舍入误差。在两个不同的系统中获得完全相同的两个值并不是那么巧合。这是偶然发生的。
eps
是机器 epsilon,可以加到 1 以获得下一个数字的最小值。添加 100 个(单位正态)随机值的结果大多恰好在 1-32 范围内,较小的值更有可能出现。我们还预计舍入误差会很小。结果的精度。所以我们应该能够将这些数字写为 <small integer> * eps(<binary magnitude of result>)
:
8.881784197001252e-15 == 5 * eps(8)
3.552713678800501e-15 == 1 * eps(16)
2.6645352591003757e-15 == 3 * eps(4)
4.440892098500626e-16 == 1 * eps(2)
1.7763568394002505e-15 == 1 * eps(8)
另请注意 MATLAB recently changed its implementation of sum
, explicitly to reduce rounding errors 。那NumPy uses a similar strategy to sum values in an array .
关于python - 随机数重新排序的总和组合成重复值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76899630/