【发布时间】:2015-08-12 08:15:47
【问题描述】:
为了提高效率,我正在将一些程序从 Matlab 移植到 C++。两个程序的输出必须完全相同 (**)。
此操作我面临不同的结果:
std::sin(0.497418836818383950) = 0.477158760259608410 (C++)
sin(0.497418836818383950) = 0.47715876025960846000 (Matlab)
N[Sin[0.497418836818383950], 20] = 0.477158760259608433 (Mathematica)
所以,据我所知,C++ 和 Matlab 都使用 IEEE754 定义的双精度算法。我想我在某处读过 IEEE754 允许在最后一位产生不同的结果。使用mathematica 来决定,似乎C++ 更接近结果。 如何强制 Matlab 精确计算包含最后一位的 sin,以使结果相同?
在我的程序中,这种行为会导致很大的错误,因为数值微分方程求解器会在最后一位中不断增加这个错误。但是我不确定 C++ 移植版本是否正确。我猜 即使 IEEE754 允许最后一位不同,以某种方式保证在更多 IEEE754 定义的双重操作中使用结果时此错误不会变大(因为否则,两个不同的程序正确根据 IEEE754 标准可以产生完全不同的输出)。所以另一个问题是我说得对吗?
我想得到两个粗体问题的答案。 编辑:第一个问题颇有争议,但不太重要,有人可以评论第二个问题吗?
注意:这不是打印错误,以防万一你想检查,这是我得到这些结果的方式:
http://i.imgur.com/cy5ToYy.png
注意(**):我的意思是最终输出,即一些计算的结果,显示一些小数点后 4 位的实数,需要完全相同。我在问题中谈到的错误变得更大(因为更多的操作,在 Matlab 和 C++ 中的每一个都是不同的)所以最终的差异是巨大的)(如果你很好奇看到差异是如何开始变大的,这里是完整的输出[链接很快],但这与问题无关)
【问题讨论】:
-
IEEE-754
doubles 的精度仅为 15–17 significant decimal digits。 -
@Trollkemada
It is important for the output of both programs to be exactly the same你会等着戈多。甚至不能保证用不同的编译器编写的 C++ 程序的行为与浮点数完全相同。 -
Re 重要的是两个程序的输出完全相同。 相反,重要的是你应该容忍一些最小的差异。您期望完全匹配但没有得到它是您的问题,而不是 C++、Matlab 或 Mathematica。你需要改变你的期望。最好不要期望跨平台、产品或什至完全相同产品的不同编译的浮点数完全匹配。
-
基于“在我的程序中,这种行为会导致很大的错误,因为数值微分方程求解器会在最后一位中不断增加这个错误。”你的问题比正弦结果的最后一点要大得多。请记住,原始输入数据可能来自测量精度远低于 10^15 中的一部分。
-
您需要考虑您尝试求解混沌方程组的可能性。微小的差异迅速变得显着是混乱的典型。
标签: c++ matlab floating-point ieee-754