以下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小了一点。)
我尝试在其他几个系统上编译相同的代码,包括运行Windows7和VSCommunity2013的旧系统,以及运行MacOS10.12和Xcode9.3.1的mac,结果与系统a一致,而不是系统B。
就在这里
真正地
奇怪的是:
结果和A系统一样!
在此期间发生了一些变化,导致编译后的程序产生不同的答案。
我的问题是:这到底是怎么发生的?!
我知道浮点运算的不精确性,我不想为将
log(a)
和
log(b)
没有四舍五入或以其他方式解释不准确。这显然是个虫子。
但是这个特定的bug在过去两周才暴露出来,而且只出现在一个系统上。我无法在其他地方复制它。
据我所知,双精度浮点运算的结果是基于CPU的,而不是操作系统、编译器、C运行时或任何其他的
.
为什么一个系统
6.0000000000
两周前突然转向生产
5.9999999999
?
(假定Windows 10喜欢自动自动更新自己,但系统B的所有者没有手动安装任何可以轻松解释此更改的更新。)
我要知道这是我内心的平静。