Следующий код на C был скомпилирован сегодня на двух системах с помощью компилятора Microsoft (установленного с Visual Studio 2017 Community), оба из которых имели современные 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, а также mac под управлением macOS 10.12 и Xcode 9.3.1, и их результаты согласовывались с системой A, а не с системой B .
Вот где это получается действительно странно:
Чтобы еще больше запутать ситуацию, когда программа была скомпилирована две недели назад в системе B , она дала тот же результат, что и система A! Что-то в промежуточном периоде изменилось, и скомпилированная программа вызвала другой ответ.
Мой вопрос: как, черт возьми, это случилось?!
Мне известна неточность с плавающей запятой, и я не пытаюсь оправдать или оправдать ошибку деления результата log(a)
и log(b)
без округления или иного учета неточности. Это явно ошибка.
Но эта конкретная ошибка появилась только в последние две недели и только в одной системе. Я не мог воспроизвести его где-либо еще.
Насколько мне известно, результат математики с плавающей запятой двойной точности основан на процессоре, а не операционной системе, компиляторе, среде выполнения C или любом другом программном обеспечении .
Почему система, которая произвела 6.0000000000
две недели назад, внезапно переключилась на производство 5.9999999999
?
(Предоставленная Windows 10 любит автоматически обновлять себя в режиме без вывода сообщений, но владелец системы B не устанавливал вручную какие-либо обновления, которые могли бы легко объяснить это изменение.)
И для собственного образования, и для душевного спокойствия мне бы очень хотелось узнать ответ на этот вопрос.