C++ 在不同的平台/编译器上实现相同的浮点计算结果?

C++ 在不同的平台/编译器上实现相同的浮点计算结果?,c++,c,double,ieee-754,fpu,C++,C,Double,Ieee 754,Fpu,不同的平台具有不同的FP能力和不同的参数和行为,因此,它们产生的计算结果之间存在一定程度的差异,这些差异在每个中间步骤上级联和放大 我所处的情况是(+-*/仅限)计算在每个不同的目标平台上使用不同的编译器供应商生成相同的结果是至关重要的,所以我想知道是否有一种标准方法可以做到这一点。我不是在问任意的高精度浮点数,而是标准的64位IEEEdouble,性能下降是可以预期的,也是可以容忍的 即使您有64位IEEE754double,也需要检查一些额外的内容 确保您有严格的浮点。例如,不要让编译器使用

不同的平台具有不同的FP能力和不同的参数和行为,因此,它们产生的计算结果之间存在一定程度的差异,这些差异在每个中间步骤上级联和放大


我所处的情况是(
+-*/
仅限)计算在每个不同的目标平台上使用不同的编译器供应商生成相同的结果是至关重要的,所以我想知道是否有一种标准方法可以做到这一点。我不是在问任意的高精度浮点数,而是标准的64位IEEE
double
,性能下降是可以预期的,也是可以容忍的

即使您有64位IEEE754
double
,也需要检查一些额外的内容

  • 确保您有严格的浮点。例如,不要让编译器使用80位进行中间计算

  • IEEE754需要各种运算(所有算术运算,如您提到的,
    std::sqrt
    ,&c),以返回可能的最佳数字。(如果您需要其他人,那么请确保您的所有操作都在IEEE754标准中提及,并且您的平台忠实地遵守该标准-可能不会)

  • 避开其他函数(如三角函数),即使在IEEE754下,也无法保证精度

  • 在您的特定情况下,(1)似乎足够了,也许(对于C++)

    static_assert(std::numeric_limits::is_iec559,“需要IEEE 754浮点”);
    
    您可以在软件中使用整数进行浮点计算。您尝试过定点库吗?我认为所有实现的结果应该是一样的。我开始觉得这太宽泛了。您在浮点类型上执行什么操作集?gcc使用mpfr库进行编译时浮点计算。所有主要的编译器都有影响浮点代码生成的选项。如果使用严格的模型,那么基本运算(+、-、*、/、sqrt)应该给出相同的结果。唯一的宽范围例外是x86 fpu,它默认使用80位精度。但是,这也可以更改为双精度(另外,gcc有选项
    -ffloat store
    。或者只使用sse而不是fpu。)C编译器可以默认为
    #pragma STDC FP_CONTRACT on
    ,允许它们将
    x*y+z
    压缩为FMA,而中间结果不进行四舍五入。同样的,同样的事情也适用于C++。GCC即使当MUL和Addio不是同一表达式的一部分时也这样做,但是在单独的语句中,违反ISO C表示这适用于C++。但是一旦你处理好了,并通过检查排除高精度的临时值来避免80位x87,你就可以使用基本的运算了,这是产生正确的四舍五入结果所必需的。关于我在回答一个类似问题时所发现的东西,请参见。
    static_assert(std::numeric_limits<double>::is_iec559, "IEEE 754 floating point required");