为什么numpy将20000001 int转换为float32为20000000。?

时间:2017-02-15 15:36:45

标签: python numpy

我试图将一些数字放入numpy数组

>>> np.array([20000001]).astype('float32')
array([ 20000000.], dtype=float32)

1去了哪里?

3 个答案:

答案 0 :(得分:8)

你根本没有足够的精确度。 float32只有大约 7位精度,而float64大约有16位精度。因此,只要您转换为float32,就只能保证"正确"大约在10 ^ 7的一部分内。所以,例如,你可以试试这个:

>>> np.array([20000001]).astype('float64')
array([ 20000001.])

这是预期的答案。 (dtype=float64会自动省略,因为这是默认值。)事实上,你可以更进一步找到

>>> np.array([2000000000000001]).astype('float64')[0]
2000000000000001.0

>>> np.array([20000000000000001]).astype('float64')[0]
20000000000000000.0

在某些时候,无论你的精确度有多高,你总能达到float s降低最低有效数字的程度。有关float s。

的详细信息,请参阅here

另一方面,python的int个对象有更多可以跟踪的数字。在python 3中,它实际上是无限的。所以int s基本上具有无限精度。有关int s。

的详细信息,请参阅here

答案 1 :(得分:2)

float32你无法解决它

>>> np.finfo(np.float32).eps
1.1920929e-07

eps这里为您提供“最小的可表示正数,使得1 + eps!= 1”,这是float32准确度的度量。将其与20,000,000相乘并且它太大了。

不那么非正式地,如果想要避免计算n的二进制表示,则eps * n / base是围绕n的分辨率的方便下界。虽然@hobbs指出eps * n是一个上限。

另请注意,例如1 + 0.6 * eps实际上可能会返回一些东西!= 1,但这是由于四舍五入。从结果中减去1会返回eps,而不是0.6 * eps。

答案 2 :(得分:2)

首先,float64适用于这种情况:

>>> np.array([20000001]).astype('float32')
array([ 20000000.], dtype=float32)
>>> np.array([20000001]).astype('float64')
array([ 20000001.])


float如何在幕后工作:

enter image description here


float32float64之间有什么区别?:

  • 32位(单精度浮点数):24位有效数字
  • 64位(双精度浮点数):53位有效数


使用float32,您将获得23位来表示数字加上1位来表示符号。让我们以二进制方式查看20000001

0b 1 0011 0001 0010 1101 0000 0001  ---->
0b 1 0011 0001 0010 1101 0000 00

因此,从int转换为float32时,最后两位“01”将被切断。

有趣的是,转换20000003会让你20000004

>>> np.array([20000003]).astype('float32')
array([ 20000004.], dtype=float32)

那就是:

0b 1 0011 0001 0010 1101 0000 0011  ---->
0b 1 0011 0001 0010 1101 0000 01