Я пытаюсь сохранить согласованные результаты вычислений с плавающей запятой для разных операционных систем, и я столкнулся с странной регрессией в отношении numpy и arcsinh при тестировании на более новых системах. Вот минимальный рабочий пример, который ведет себя по-разному в разных системах.
#!/usr/bin/env python
import struct
from numpy import (array, arcsinh, float32)
def float_to_hex(f):
return hex(struct.unpack('<I', struct.pack('<f', f))[0])
numpy_result = arcsinh(array([3.0], dtype=float32))[0]
print("asinh(3.0):", numpy_result, float_to_hex(numpy_result))
На Centos 7 и Ubuntu 16.04 я получаю следующий результат:
asinh(3.0): 1.8184464 0x3fe8c2da
На Ubuntu 18.04 (и Windows, по словам коллеги) я получаю следующий результат:
asinh(3.0): 1.8184465 0x3fe8c2db
Было бы здорово понять, почему это происходит, и как получить согласованный результат в разных системах. Идеально придерживается 32-битного решения с плавающей запятой. Есть ли какая-то непонятная опция, которую я пропускаю, которая меняется в разных операционных системах?
Примечательно, что я не могу воспроизвести это с помощью C-программы. С помощью asinh GLIBC (32-разрядного числа с плавающей запятой 3.0) я всегда получаю новый результат 1.8184465 и его шестнадцатеричное представление 0x3fe8c2db независимо от того, в какой системе я работаю. Это, кажется, специфично для numpy.
Мой рабочий пример C:
#include <stdio.h>
#include <math.h>
int main() {
float value = asinhf(3.0f);
unsigned int hexValue = *(unsigned int *)&value;
printf("Plain value: %.7f\n", value);
printf("Hex value: 0x%8x\n", hexValue);
return 0;
}
Я также могу убедиться, что в системах используется одна и та же клочковатая версия. В этом случае это 1.15.3. Пакет numpy был установлен с колес повсюду, поэтому установлены одни и те же библиотеки общих объектов. Для здравого смысла я дважды проверил библиотеки, выполнив операцию file
на всех из них во всех системах.
Я полагаю, что согласно IEEE 754 последняя значащая цифра 5 (для arcsinh из 3.0) является правильной, поскольку она должна округляться от нуля. Тем не менее, решение, в котором результат является согласованным, для меня важнее.
Спасибо за ваше время.