Точность [с] плавающей запятой программы на С, при работе на той же машине, изменилась за последние две недели - PullRequest
0 голосов
/ 16 сентября 2018

Следующий код на 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 не устанавливал вручную какие-либо обновления, которые могли бы легко объяснить это изменение.)

И для собственного образования, и для душевного спокойствия мне бы очень хотелось узнать ответ на этот вопрос.

...