如何保证在不同系统上相同的浮点数? [英] How to ensure same float numbers on different systems?

查看:191
本文介绍了如何保证在不同系统上相同的浮点数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我编译继Windows和Linux(Ubuntu的)C线我得到不同的结果。我想避免的。我该怎么办呢?

If I compile following c lines on windows and linux(ubuntu) I get different results. I would like to avoid. How can I do it?

 double a = DBL_EPSILON;
 double b = sqrt(a);
 printf("eps = %.20e\tsqrt(eps) = %.20e\n", a, b);

Linux输出:

linux output:

eps = 2.22044604925031308085e-16        sqrt(eps) = 1.49011611938476562500e-08

窗口输出:

eps = 2.22044604925031310000e-016       sqrt(eps) = 1.49011611938476560000e-008

在用gcc和铿锵的32位和64位系统相同的结果,测试的Linux。
在与海湾合作委员会,MinGW的32位和视觉工作室的32位和64位,也是同样的结果测试窗口。

On linux tested with gcc and clang on 32-bit and 64-bit system same result. On windows tested with gcc-mingw on 32-bit and visual-studio with 32-bit and 64-bit, also same results.

推荐答案

在你给的例子,似乎这两个方案都在相同浮点数。他们只是把它们打印不同。围绕这一特殊问题最简单的办法是写自己的浮点打印功能。如果你没想到太好的输出,你可以使用该函数的这里伪code为C.编写自己这不是正确舍入,但它的工作原理它所适用于(即,重现性和可读性输出)。

In the example you give, it seems both programs have the same floating-point numbers. They just print them differently. The simplest solution around this particular issue is to write your own floating-point printing function. If you are not expecting too nice an output, you could use the function here as pseudocode for writing your own in C. It is not correctly rounded, but it works for what it is intended for (that is, reproducible and readable outputs).

这是你的问题提示您遇到一个更深层次的问题是浮点计算让不同在不同平台上的结果。这是C标准(S)不会强迫编译器准确执行IEEE 754浮点标准,具体而言,允许中间结果高出precision的结果。和C标准(S)的这种相对宽大的至少部分是由历史的x86浮点指令使得实施的确切IEEE 754语义它昂贵造成的。

A deeper issue that your question hints you are encountering is floating-point computations giving different results on different platforms. This is a result of the C standard(s) not forcing compilers to implement the IEEE 754 floating-point standard exactly, specifically, allowing higher precision for intermediate results. And this relative leniency of the C standard(s) is caused at least in part by the historical x86 floating-point instructions making it expensive to implement the exact IEEE 754 semantics.

在Linux中,假设你使用GCC,请尝试 -msse2 编译选项。 修改:OP的评论说, -msse2 -mfpmath = SSE 为他工作
这使得GCC产生现代SSE2指令给出确切的IEEE 754浮点语义。如果在Windows上使用的是GCC也使用相同的选项那里。

On Linux, assuming you are using GCC, try the -msse2 compilation option. the OP commented that -msse2 -mfpmath=sse worked for him. This makes GCC generate modern SSE2 instructions that give the exact IEEE 754 floating-point semantics. If on Windows you are using GCC too, use the same option there.

如果您正在使用Visual C:的Visual C使用了另一种技巧,迫使历史浮点指令匹配IEEE 754语义:它告诉老80位浮点硬件只使用尽可能多的有效数位作为IEEE 754双precision了。这给了双precision数字的精确模拟,除了少数极端情况,你将不会被遇到。在这种情况下,这将有助于(*)如果你的程序只使用双precision号(的C 双击键入)。

If you are using Visual C: Visual C uses another trick to force the historical floating-point instructions to match IEEE 754 semantics: it tells the old 80-bit floating-point hardware to use only as many significand bits as IEEE 754 double-precision has. That gives an accurate simulation of double-precision numbers, except for a few corner cases that you will not be encountering. In this case it would help(*) if your program used only double-precision numbers (the C double type).

(*)在Visual C编译器理论上可以产生code,它由双单precision四舍五入每个中间结果计算准确的单precision算术,但是这将是昂贵的,我对此表示怀疑做这个。

(*) The Visual C compiler could theoretically generate code that computes exact single-precision arithmetics by rounding each intermediate result from double to single precision, but this would be expensive and I doubt it does this.

这篇关于如何保证在不同系统上相同的浮点数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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