如果两种语言遵循IEEE 754,两种语言的计算会产生相同的答案吗?

Pau*_*ick 10 c++ floating-point precision rounding-error scilab

我正在将程序从Scilab代码转换为C++.特别是一个循环产生的结果与原始的Scilab代码略有不同(这是一段很长的代码,因此我不会在问题中包含它,但我会尽力总结下面的问题).

问题是,循环的每一步都使用上一步的计算.此外,计算之间的差异仅在第100,000次迭代(大约300,000次)中变得明显.

注意:我正在使用"format(25)"将我的C++程序的输出与Scilab 5.5.2的输出进行比较.命令.含义我正在比较25位有效数字.我还想指出,我理解在一定数量的位之后无法保证精度,但在评论之前阅读下面的部分.到目前为止,两种语言之间的所有计算都相同,最多可达25位.

为了找到问题的根源,到目前为止我已经尝试过:

  1. 检查正在使用的数据类型:

我已经设法确认Scilab正在使用IEEE 754双打(根据语言文档).另外,根据维基百科,C++ 并不需要使用IEEE 754双打,但我可以告诉,我到处使用双C++中它已完全匹配的Scilab的结果.

  1. 检查超越函数的使用:

我还读过每个计算机科学家应该知道的关于浮点运算的内容,IEEE不要求超越函数完全舍入.考虑到这一点,我在两种语言中比较了这些函数的结果(sin(),cos(),exp()),结果看起来是相同的(最多25位).

  1. 使用其他功能和预定义值:

我重复了上述步骤,以便使用sqrt()和pow().以及Pi的值(我在C++中使用M_PI,在Scilab中使用%pi).同样,结果是一样的.

  1. 最后,我重写了循环(非常仔细),以确保两种语言之间的代码相同.

注意:有趣的是,我注意到,对于上述所有计算,两种语言之间的结果与计算的实际结果(浮点运算之外)相匹配得更远.例如:

使用Wolfram Alpha = sin(x)的值= 0.123456789 .....

使用Scilab&C++ = sin(x)的值= 0.12345yyyyy .....

甚至一旦使用Scilab或C++计算的值开始与实际结果不同(来自Wolfram).每种语言的结果仍然相互匹配.这使我相信大多数值都以相同的方式计算(在两种语言之间).即使IEEE 754不要求它们.


我最初的想法是上述前三点之一,两种语言之间的实现方式不同.但据我所知,一切似乎都会产生相同的结果.

是否有可能即使这些循环的所有输入都相同,结果也可能不同?可能是因为一个非常小的错误(过去我能看到的25位数)正在发生,随着时间累积?如果是这样,我该如何解决这个问题呢?

Jim*_*wis 6

某些体系结构提供了使用扩展精度浮点寄存器的能力(例如,内部为80位,而RAM中为64位).因此,对于相同的计算,可能会得到略微不同的结果,具体取决于计算的结构,以及用于编译代码的优化级别.


Tho*_*ews 6

不,编号系统的格式不保证来自不同语言的功能的等效答案.

诸如的功能sin(x)可以使用相同的语言(以及不同的语言)以不同的方式实现.该sin(x)功能是一个很好的例子.许多实现将使用具有插值的查找表或查找表.这具有速度优势.然而,一些实现可以使用泰勒级数来评估函数.一些实现可以使用多项式来得出近似的近似值.

具有相同的数字格式是语言之间解决的一个障碍.功能实现是另一个.

请记住,您还需要考虑该平台.使用80位浮点处理器的程序与使用64位浮点软件实现的程序的结果不同.

  • @PaulWarnick:编译器手册中记录了C++编译器是否实现IEEE 754浮点表示.不需要C++语言的实现来使用任何给定的浮点表示. (3认同)