我正在将一个程序从Scilab代码转换为C ++。特别是一个循环产生的结果与原始的Scilab代码略有不同(这是一段长代码,所以我不会在问题中包含它,但我会尽力总结下面的问题)。
问题是,循环的每个步骤都使用前一步的计算。此外,仅在第100,000次迭代(约为300,000次迭代之一)时才出现计算之间的差异。
注意:我正在使用“format(25);”命令将我的C ++程序的输出与Scilab 5.5.2的输出进行比较。这意味着我正在比较25个有效数字。 我还想指出,在评论之前,请阅读以下部分。到目前为止,两种语言之间的所有计算都相同,最多可达25位小数。
为了找出问题的根源,到目前为止我已经尝试过:
- 检查所使用的数据类型:
我已成功确认Scilab正在使用IEEE 754双精度浮点数(根据语言文档)。 此外,根据维基百科,C ++不需要对双精度浮点数使用IEEE 754,但从我所知道的,我在C ++中使用double的每个地方都与Scilab的结果完全匹配。
- 检查超越函数的使用:
我还从What Every Computer Scientist Should Know About Floating-Point Arithmetic中了解到,IEEE不要求将超越函数精确四舍五入。考虑到这一点,我比较了两种语言中这些函数(sin(),cos(),exp())的结果,结果看起来是相同的(最多达到25位小数)。
- 其他函数和预定义值的使用:
我对sqrt()和pow()函数的使用,以及圆周率的值进行了与前面相同的步骤(在C++中使用M_PI,在Scilab中使用%pi)。结果仍然相同。
- 最后,我非常小心地重写了循环,以确保两种语言之间的代码完全相同。
注意:有趣的是,我发现所有上述计算结果在两种语言之间的匹配程度远高于实际计算结果(在浮点运算以外)。例如:
使用Wolfram Alpha计算sin(x)的值 = 0.123456789......
使用Scilab和C++计算sin(x)的值 = 0.12345yyyyy......
即使使用Scilab或C++计算出的值开始与实际结果(来自Wolfram)不同,每种语言的结果仍然彼此匹配。这让我相信大部分值是以相同的方式计算出来的(在两种语言之间),尽管它们不必按照IEEE 754标准。
我的最初想法是前三点中有一些东西在两种语言之间实现方式不同。但据我所知,似乎所有内容都可以产生相同的结果。
即使这些循环的所有输入都相同,它们的结果可能会不同吗?可能是由于一个非常小(超出我所能看到的25位数字)的错误随着时间的推移而累积导致的吗?如果是这样,我该如何解决这个问题?
/fp:strict
。使用这样的标志可能会损失很多性能。 - njuffa