Почему это сравнение с одинарной и двойной точностью не дает результата? - PullRequest
1 голос
/ 24 сентября 2019

Дано:

val = 1e20
a = np.array(val); b = np.array(val, 'f4')

Я не понимаю, почему a == b является ложным, а np.allclose(a, b) - истинным.Ведь диапазон чисел с плавающей запятой одинарной точности составляет ~ 10 ^ 38.На самом деле, поскольку np.can_cast(1e20, 'f4') является Истиной, я ожидаю, что приведенное выше равенство должно быть действительным.

Я полагаю, что это может иметь какое-то отношение к причудливости в представлении чисел с плавающей запятой, но я неполностью понять, что именно здесь может происходить внутри.

1 Ответ

1 голос
/ 24 сентября 2019

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

In [41]: print('{}'.format(a))
1e+20

In [42]: print('{}'.format(b))
1.00000002004e+20

Причиной является то, что в 64-битном a есть:

0100 0100 0001 0101 1010 1111 0001 1101 0111 1000 1011 0101 1000 1100 01000000

со знаковым битом 0, затем 11-битнымэкспонента 100 0100 0001, а остальное для мантиссы.Приведение его к 32-битному и обратно для полос сравнения последних битов мантиссы:

0100 0100 0001 0101 1010 1111 0001 1101 1000 0000 0000 0000 0000 0000 00000000

Сравнение чисел с плавающей запятой может вводить в заблуждение, поскольку оператор == проверяет точную двоичную эквивалентность.В зависимости от вашего намерения, вы можете рассмотреть возможность проверки уровня соглашения, например:

if fabs(a-b) < 1E-6: 
  print('equal')
...