编译器之间的浮点不匹配(Visual Studio 2010和GCC) [英] Floating point mismatch between compilers (Visual Studio 2010 and GCC)

查看:234
本文介绍了编译器之间的浮点不匹配(Visual Studio 2010和GCC)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图解决的裁剪了一个跨平台的问题,我不知道怎么和去做。这里有一个演示程序:

I'm trying to solve a cross-platform issue that's cropping up and I'm not sure quite how to go about it. Here's a demonstration program:

#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);
}

当VS2010编译Windows上的输出是:

The output on Windows when compiled in VS2010 is:

0.885638 3f62b92a

输出时使用GCC 4.8.1 (ideone.com样品)是编译:

The output when compiled with GCC 4.8.1 (ideone.com sample) is:

0.885638 3f62b92b

这些小的失配最终气球到超过需要在多个平台上相同运行程序的过程中的严重问题。我不担心这么多关于准确度作为结果的相互匹配的。我试图切换 / FP 模式VS为 precise ,但这似乎并没有解决它。

These small mismatches end up ballooning into a serious problem over the course of a program that needs to run identically on multiple platforms. I'm not concerned so much about "accuracy" as that the results match each other. I tried switching the /fp mode in VS to strict from precise, but that doesn't seem to fix it.

我应该看什么其他途径在做这种计算有两个平台上相同的结果?

What other avenues should I look at to make this calculation have the same result on both platforms?

更新:有趣的是,如果我改变code这样的,它在整个平台相匹配:

UPDATE: Interestingly, if I change the code like this, it matches across the platforms:

#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);
}

我不知道这是真实的,但是,通过code走路和改变这样所有浮点操作!

I'm not sure it's realistic, however, to be walking through the code and changing all floating point operations like this!

推荐答案

摘要:这是一般不被编译器的支持,你将有一个艰难的时间在一个更高层次的语言做它,你将需要使用一个数学图书馆共同所有的目标平台。

Summary: This is generally not supported by compilers, you will have a tough time doing it in a higher-level language, and you will need to use one math library common to all your target platforms.

C和C ++语言标准允许实现了相当多的灵活性(太多)的浮点运算。许多C和C ++浮操作不必须遵守的方式在IEEE 754-2008标准可能是直观很多程序员

The C and C++ language standards allow implementations a considerable amount (too much) of flexibility in floating-point operations. Many C and C++ floating-operations are not required to adhere to the IEEE 754-2008 standard in the way that might be intuitive to many programmers.

甚至很多C和C ++实现不为宗旨,秉承IEEE 754-2008标准提供良好的支持。

Even many C and C++ implementations do not provide good support for adhering to the IEEE 754-2008 standard.

数学库的实现是一个特别的问题。不存在,提供了正确舍入的结果适用于所有标准数学函数任何正常库(市售或广泛使用的开放源码与已知的有界运行时间)。 (获取正确的数学上的一些功能是一个非常棘手的问题。)

Math library implementations are a particular problem. There does not exist any normal library (commercially available or widely-used open source with a known-bounded run-time) that provides correctly rounded results for all standard math functions. (Getting the mathematics right on some of the functions is a very difficult problem.)

开方,但比较简单,应在合理质量的库返回正确舍入的结果。 (我不能担保微软执行。)它更可能在code您展示特定问题是编译器的选择使用浮点的不同precisions在评估前pressions。

sqrt, however, is relatively simple and should return correctly rounded results in an library of reasonable quality. (I am unable to vouch for the Microsoft implementation.) It is more likely the particular problem in the code you show is the compiler’s choice to use varying precisions of floating-point while evaluating expressions.

有可能是你可以用不同的编译器使用,要求他们遵守有关浮点行为的某些规则的各种开关。这些可能足以为获得基本的操作来达到预期效果。如果不是,汇编语言是访问定义良好的浮点运算的方法。但是,除非你提供一个公共库库例程的行为将是平台之间的不同。这既包括数学库例程(如 POW ),并在程序中转换,例如 fprintf中的fscanf strtof 。因此,你必须找到支持所有您指定的平台之一精心设计的执行每次依赖于常规的。 (必须精心设计的,因为它提供了在所有平台上相同的行为感。数学上,它可以是有些不精确的,只要它是边界容忍的应用程序中。)

There may be various switches you can use with various compilers to ask them to conform to certain rules about floating-point behavior. Those may be sufficient for getting elementary operations to perform as expected. If not, assembly language is a way to access well-defined floating-point operations. However, the behavior of library routines will be different between platforms unless you supply a common library. This includes both math library routines (such as pow) and conversions found in routines such as fprintf, fscanf, strtof. You must therefore find one well-designed implementation of each routine you rely on that is supported on all of the platforms you target. (It must be well-designed in the sense that it provides identical behavior on all platforms. Mathematically, it could be somewhat inaccurate, as long as it is within bounds tolerable for your application.)

这篇关于编译器之间的浮点不匹配(Visual Studio 2010和GCC)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆