为什么np.float32稍微改变了矩阵中的值而np.float64没有?

时间:2017-11-24 09:17:52

标签: python numpy floating-point

当我将矩阵中的数字转换为np.float32时,值会略微修改:

In [1]: matrix_32 = np.asarray([
   ...:    [0.7, 3],
   ...:    [1.7, 2],
   ...:    [0.7, 9]
   ...: ], dtype=np.float32)

In [2]: matrix_32
Out[2]: 
array([[ 0.69999999,  3.        ],
       [ 1.70000005,  2.        ],
       [ 0.69999999,  9.        ]], dtype=float32)

但是,当我将数字转换为np.float64时,值会按预期显示:

In [3]: matrix_64 = np.asarray([
   ...:    [0.7, 3],
   ...:    [1.7, 2],
   ...:    [0.7, 9]
   ...: ], dtype=np.float64)

In [4]: matrix_64
Out[4]: 
array([[ 0.7,  3. ],
       [ 1.7,  2. ],
       [ 0.7,  9. ]])

有人可以解释为什么会这样吗?

1 个答案:

答案 0 :(得分:3)

当十进制数转换为二进制浮点数时,它们必须舍入为二进制分数而不是十进制。这种舍入会改变这些值。对于float32,更改足够大,可以在Numpy使用的输出格式中看到。对于float64,更改太小而无法看到。

您显示的Numpy示例似乎使用八位小数或九位有效数字。对于正常的float32值,由十进制转换引起的更改往往是转换值的大约.00000003倍(并且大到两倍),因此它们以九位有效数字显示。对于正常的float64值,由十进制转换引起的更改往往是该值的.0000000000000001(10-16)倍,因此它们太小而无法以九位有效数字显示。

对于正常的float32值,更改可能会在16,777,216中大到1个部分。对于正常的float64值,更改可能大到9,007,199,254,740,992中的1个部分。这仅适用于从十进制到二进制浮点的初始转换。进行算术运算时可能会有额外的舍入(精确的数学结果四舍五入到适合浮点格式的值),并且当数字转换回十进制数以便显示时。 (在正常范围之外,非常大的数字可能溢出到无穷大[所以变化是无限的],并且非常小的数字更粗略地舍入[对于最小的数字甚至为零,因此变化高达100%]。)