c - 在同一台机器上运行时,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
但是对于c
和result
系统 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 的所有者并没有手动安装任何可以轻松解释此更改的更新。)
为了我自己的教育和内心的平静,我真的很想知道这个问题的答案。
解决方案
推荐阅读
- python - 使用 pytesseract 执行 OCR 时出错
- c# - 具有依赖瞬态的 ASP.NET Core DI
- mysql - MySQL:如何根据最高修订号计算数据记录集?
- javascript - 类名中的参数
- javascript - vue js复选框,将json对象作为值传递给模型
- javascript - Ember.js 每个循环:将当前索引数据与之前的索引数据进行比较
- android - 如何解决“您的应用似乎未启用 Places API for Android”
- php - Laravel MS SQL 登录超时已过期
- git - Git Flow,从 master 签出分支,rebase 以开发
- android - FastCSV 文件处理失败