Даже без -Ofast
стандарт C ++ не требует, чтобы реализации были точными с log
(или sin
, или exp
и т. Д.), Только чтобы они находились в пределах нескольких ульп (т.е. могутбудут некоторые неточности в последних двоичных местах).Это позволяет ускорить аппаратное (или программное) приближение, которое каждая платформа / компилятор может выполнять по-разному.
() Единственная математическая функция с плавающей запятой, с которой вы всегда получите идеальные результаты на всех платформах, - это sqrt
. )
Более досадно, что вы даже можете получить разные результаты между компиляцией (компилятор может использовать некоторую внутреннюю библиотеку, чтобы быть настолько точной, как float
/ double
допускает постоянные выражения) и временем выполнения (например, аппаратные аппроксимации).
Если вы хотите, чтобы log
давал одинаковый результат на разных платформах и компиляторах, вам придется реализовать его самостоятельно, используя только +
, -
, *
, /
и sqrt
(или найдите библиотеку с этой гарантией).И избегайте целого ряда ловушек на этом пути.
Если вам нужен детерминизм с плавающей запятой в целом, я настоятельно рекомендую прочитать эту статью, чтобы понять, насколько серьезна проблема у вас впереди: https://randomascii.wordpress.com/2013/07/16/floating-point-determinism/