我有一个用C编写的相当大的模型(约5000行)。它是一个串行程序,在任何地方都没有随机数的产生。它将FFTW库用于使用FFT的函数-我不知道FFTW实现的详细信息,但是我假设其中的函数也是确定性的(如果我出错,请更正我)。
我无法理解的问题是,在同一台计算机(相同的编译器,相同的库)上运行相同的结果在结果上存在很小的差异。
我使用双精度变量,并将结果输出到变量中value
,例如,我发出:
fprintf(outFID, "%.15e\n", value);
或
fwrite(&value, 1, sizeof(double), outFID);
而且我会不断得到诸如以下的差异:
2.07843469652206 4 e-16与2.07843469652206 3 e-16
我花了很多时间试图找出原因。最初我以为我的一个存储芯片已经坏了,所以我下令更换了它们,无济于事。随后,我还尝试在同事的Linux机器上运行我的代码,并且得到了相同性质的差异。
是什么原因造成的?现在这是一个小问题,但我想知道这是否是“冰山一角”(一个严重的问题)。
我以为我会在这里发布而不是StackOverflow,以防有人使用数值模型。如果有人可以阐明这一点,我将非常有义务。
评论后续:
Christian Clason和Vikram:首先,感谢您对我的问题的关注。您链接的文章建议:1.舍入错误限制了准确性,并且2.不同的代码(例如引入看似无害的打印语句)可能会影响机器的结果。我要澄清的是,我没有比较效果fwrite
和fprintf
功能。我正在使用一个或另一个。特别是,两次运行都使用相同的可执行文件。我只是在说明是否使用fprintf
OR 发生问题fwrite
。
因此,代码路径(和可执行文件)相同,硬件也相同。在所有这些外部因素保持不变的情况下,随机性从何而来呢?我怀疑由于错误的内存无法正确保留位而发生了位翻转,这就是为什么我更换了内存芯片的原因,但是我证实这并不是这里的问题,我证实并指出。我的程序在一次运行中输出了数千个这种双精度数字,并且总是有随机的少数具有随机的位翻转。
跟帖基督教克拉森的第一个评论:为什么是机器精度内一样的0?双精度数的最小正数是2.22e-308,那不等于0吗?我的程序输出10 ^ -16范围(从1e-15到8e-17)的数千个值,并且我们一直在研究项目中看到有意义的变化,所以我希望我们不要一直在研究荒谬的东西。数字。