【发布时间】:2012-03-01 15:22:50
【问题描述】:
我已经将一个相对简单的算法从 C++ 转换为对 double 类型的数字执行大量计算的 Java,但是在两个平台上运行该算法但同一台机器产生的结果略有不同。该算法将许多双精度数和整数相乘并求和。我在 Java 算法中将整数加倍; C 算法不强制转换。
例如,在一次运行中,我得到了结果:
- (Java) 64684970
- (C++) 65296408
(打印忽略小数位)
当然,我的算法可能存在错误,但是在我开始花时间调试之前,是否可以通过 C++ 和 Java 中的不同浮点处理来解释差异?如果是,我能证明这是问题所在吗?
更新 - 类型不同的地方是两个整数之间的乘法,然后将其添加到运行总双精度数中。 修改了 C 代码,目前在两者中:
mydouble += (double)int1 * (double)int2
【问题讨论】:
-
您在 Java 版本中使用了什么数据类型?
-
差别很大,我怀疑这可能是由舍入错误引起的。我的猜测是你在某个地方犯了错误。除非你做一些极端的事情,比如除以 1E300 之类的。
-
浮点错误累积到 1% 的差异的可能性很小,但如果您运行的算法在数值上不稳定,这当然是可能的(“不稳定”意味着大约是“混乱的小弟”) .显然,从结果中无法判断您没有在 Java 代码中意外写入
result -= 611438,因此仅通过查看结果。但是,如果您可以使用float代替double在 C++ 中运行计算,那么您可能会知道精度的重要性。 -
使用调试器或打印语句,以全精度显示算法中的每个中间值。希望这将确定值开始分歧的单个步骤。当您确定了这一步后,请回到我们这里。
-
您还可以根据代码的优化方式获得差异。例如
0.1 + 0.1 + 0.1 + 0.1 + 0.1与5 * 0.1我不希望根据您的操作而得到小于第 12 到第 15 位的差异。
标签: java c++ floating-point