首页 > 解决方案 > 在同一台机器上运行时,C 程序的浮点 [in] 精度在过去两周内发生了变化

问题描述

以下 C 代码今天在两个使用 Microsoft 编译器(随 Visual Studio 2017 社区安装)的系统上编译,这两个系统都具有现代 64 位 Intel 处理器并运行 Windows 10:

#include <math.h>
#include <stdio.h>

int main() {
    int a = 64, b = 2;
    double logA = log(a);
    double logB = log(b);
    double c = logA / logB;
    printf("logA: %0.20lf\n", logA);
    printf("logB: %0.20lf\n", logB);
    printf("c: %0.20lf\n", c);
    printf("result: %d\n", ((int)c));
    return 0;
}

让我们称它们为“系统 A”和“系统 B”以保持清晰。logA两个系统都为和打印了完全相同的值logB

logA: 4.15888308335967149532
logB: 0.69314718055994528623

但是对于cresult系统 A 打印:

c: 6.00000000000000000000
result: 6

...和系统 B 打印:

c: 5.999999999999...
result: 5

(我不再知道它产生的确切结果,但我只想说它比 6.0 略小。)

我尝试在其他几个系统上编译相同的代码,包括运行 Windows 7 和 VS Community 2013 的旧系统以及运行 macOS 10.12 和 Xcode 9.3.1 的 mac,它们的结果与系统 A 一致,而不是系统 B。

这就是它变得非常奇怪的地方:

更令人困惑的是,当程序在两周前在系统 B 上编译时,它产生的结果与系统 A 相同!在此期间发生了一些变化,导致编译的程序产生了不同的答案。

我的问题是:这到底是怎么发生的?!

我知道浮点数的不准确性,我并没有试图证明或原谅将结果除以log(a)log(b)不四舍五入或以其他方式解释不准确性的错误。这显然是一个错误。

但是这个特殊的错误只在过去两周内出现,而且只在一个系统上出现。我无法在其他任何地方复制它。

据我所知,双精度浮点数学的结果是基于 CPU,而不是操作系统、编译器、C 运行时或任何其他软件

为什么6.0000000000两周前生产的系统会突然切换到生产5.9999999999

(虽然 Windows 10 喜欢默默地自动更新自己,但系统 B 的所有者并没有手动安装任何可以轻松解释此更改的更新。)

为了我自己的教育和内心的平静,我真的很想知道这个问题的答案。

标签: cx86floating-pointintelfloating-accuracy

解决方案


推荐阅读