gpt4 book ai didi

c - 如何确保不同系统上的 float 相同?

转载 作者:太空狗 更新时间:2023-10-29 17:08:53 26 4
gpt4 key购买 nike

如果我在 windows 和 linux(ubuntu) 上编译以下 c 行,我会得到不同的结果。我想避免。我该怎么做?

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

Linux 输出:

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

windows 输出:

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

在 Linux 上使用 gcc 和 clang 在 32 位和 64 位系统上测试的结果相同。在 32 位的 gcc-mingw 和 32 位和 64 位的 visual-studio 测试的 Windows 上,结果也相同。

最佳答案

在您给出的示例中,两个程序似乎都具有相同 float 。他们只是以不同的方式打印它们。围绕这个特定问题的最简单解决方案是编写您自己的浮点打印函数。如果您不期望输出太好,可以使用函数 here作为用 C 语言编写您自己的伪代码。它没有正确舍入,但它适用于它的预期目的(即,可重现和可读的输出)。


你的问题暗示你遇到的一个更深层次的问题是浮点计算在不同平台上给出不同的结果。这是 C 标准没有强制编译器准确地实现 IEEE 754 浮点标准的结果,特别是允许更高的中间结果精度。 C 标准的这种相对宽松至少部分是由于历史 x86 浮点指令使得实现精确的 IEEE 754 语义变得昂贵。

在 Linux 上,假设您使用的是 GCC,请尝试使用 -msse2 编译选项。 编辑:OP 评论说 -msse2 -mfpmath=sse 为他工作。这使得 GCC 生成现代 SSE2 指令,提供精确的 IEEE 754 浮点语义。如果在 Windows 上您也在使用 GCC,请在那里使用相同的选项。

如果您使用的是 Visual C:Visual C 使用另一个技巧来强制历史浮点指令匹配 IEEE 754 语义:它告诉旧的 80 位浮点硬件只使用与 IEEE 754 一样多的有效位 double 了。这给出了 double 字的准确模拟,除了一些您不会遇到的极端情况。在这种情况下,如果您的程序仅使用 double 字(C double 类型),它会有所帮助(*)。

(*) 理论上,Visual C 编译器可以生成代码,通过将每个中间结果从 double 舍入为单精度来计算精确的单精度算术,但这样做会很昂贵,我怀疑它是否会这样做。

关于c - 如何确保不同系统上的 float 相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13571073/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com