编译器之间的浮点不匹配(Visual Studio 2010和GCC)

aar*_*rkk 7 c c++ floating-point gcc visual-studio-2010

我正在努力解决一个正在出现的跨平台问题,我不知道该怎么做.这是一个演示程序:

#include <cmath>
#include <cstdio>

int main()
{
    int xm = 0x3f18492a;
    float x = *(float*)&xm;
    x = (sqrt(x) + 1) / 2.0f;
    printf("%f %x\n", x, *(int*)&x);
}
Run Code Online (Sandbox Code Playgroud)

在VS2010中编译时,Windows上的输出是:

0.885638 3f62b92a

使用GCC 4.8.1 (ideone.com示例)编译时的输出是:

0.885638 3f62b92b

在需要在多个平台上运行相同的程序的过程中,这些小的不匹配最终会成为一个严重的问题.我并不太关心"准确性",因为结果相互匹配.我试着开关/fp在VS模式strictprecise,但这似乎并没有解决它.

我应该考虑采用哪些其他途径来进行此计算,在两个平台上都有相同的结果?

更新:有趣的是,如果我更改这样的代码,它会跨平台匹配:

#include <cmath>
#include <cstdio>

int main()
{
    int xm = 0x3f18492a;
    float x = *(float*)&xm;
    //x = (sqrt(x) + 1) / 2.0f;
    float y = sqrt(x);
    float z = y + 1;
    float w = z / 2.0f;
    printf("%f %x %f %x %f %x %f %x\n", x, *(int*)&x, y, *(int*)&y, z, *(int*)&z, w, *(int*)&w);
}
Run Code Online (Sandbox Code Playgroud)

但是,我不确定是否可以通过代码来改变这样的所有浮点运算!

Eri*_*hil 6

简介:编译器通常不支持这一点,您将很难用更高级的语言进行操作,并且需要使用所有目标平台通用的一个数学库.

C和C++语言标准允许在浮点运算中实现相当大(太多)的灵活性.许多C和C++浮动操作不需要遵循IEEE 754-2008标准,这对许多程序员来说可能是直观的.

甚至许多C和C++实现也没有为遵守IEEE 754-2008标准提供良好的支持.

数学库实现是一个特殊问题.不存在任何普通库(商业上可用或广泛使用的具有已知有界运行时的开源),它为所有标准数学函数提供正确的舍入结果.(在一些函数上获得正确的数学是一个非常困难的问题.)

sqrt但是,相对简单,应该在合理质量的库中返回正确的舍入结果.(我无法保证Microsoft的实现.)您展示的代码中的特定问题更可能是编译器在评估表达式时使用不同的浮点精度的选择.

可能有各种开关可以与各种编译器一起使用,要求它们遵守关于浮点行为的某些规则.这些可能足以使基本操作按预期执行.如果不是,汇编语言是一种访问定义良好的浮点运算的方法.但是,除非您提供公共库,否则库例程的行为在平台之间会有所不同.这既包括数学库例程(如pow)和例程,如发现转化fprintf,fscanf,strtof.因此,您必须找到所依赖的每个例程的一个精心设计的实现,并在您定位的所有平台上得到支持.(它必须精心设计,因为它在所有平台上提供相同的行为.从数学上讲,它可能有些不准确,只要它在你的应用程序可以容忍的范围内.)


Pau*_*ans 0

您希望它们都使用IEEE 754 标准