Погрешность вычислений с числами с плавающей запятой

В ходе всех этих развлечений с оптимизациями обнаружился интересный, но очень неприятный эффект. Результат вычислений для разных компиляторов и разных флагов оптимизации порой значительно менялся.
Для более удобного наблюдения этого эффекта был выбран простой пример(полный код на github):

В этом маленьком тесте изменение результата от изменения флагов обнаружить не удалось, но всё равно обилие результатов удивляет — 5 различных, с 13 совпадающими знаками из 15-17 возможных для double.

Исходник и компилятор Результат Время выполнения, с
Assembler 1.53436944477410652787 3.81
gcc long 1.53436944477462278158 4.4
gcc double 1.53436944477389380914 4.4
icc long 1.53436944477397574360 6.88
icc double 1.53436944477334602510 1.50

*результаты по одному измерению, по этому совсем серьёзно воспринимать их не стоит. Время указано для процессора FX-8120
p.s. ну и обнаружилось, что написание кода на ассемблере пока ещё не абсолютно потеряло смысл — получился до 15% быстрее, чем на C.

Yuriy Nazarov on GithubYuriy Nazarov on Twitter
Yuriy Nazarov
Software engineer
Люблю machine learning