为什么单精度和双精度比较在numpy中失败?

时间:2019-09-24 19:50:32

标签: python numpy floating-point

给出:

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

我不明白为什么a == b是False,而np.allclose(a, b)是True。毕竟,单精度浮点数的范围是〜10 ^ 38。实际上,由于np.can_cast(1e20, 'f4')为True,所以我希望上面的相等性是有效的。

我想这可能与浮点数表示中的古怪性有关,但是我不完全了解内部可能到底发生了什么。

1 个答案:

答案 0 :(得分:1)

原因确实是二进制形式的浮点表示:

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,其余为尾数。将其转换为32bit并进行比较以剥离尾数的最后几位:

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

比较浮点数可能会引起误解,因为==运算符会检查确切的二进制等价项。根据您的意图,您可以考虑检查协议级别,例如:

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