【问题标题】:Why does np.float32 slightly change the values in the matrix while np.float64 doesn't?为什么 np.float32 会稍微改变矩阵中的值而 np.float64 不会?
【发布时间】:2017-11-24 09:17:52
【问题描述】:

当我将矩阵中的数字转换为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. ]])

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

【问题讨论】:

  • 我建议你阅读一些浮点运算的介绍,例如en.wikipedia.org/wiki/Floating-point_arithmetic
  • 问题不仅在于引入的不准确性,还在于np.float32np.float64 似乎对它们的对象有不同的__repr__ 实现。
  • 我知道我们得到了很多浮点问题,这些问题很容易通过了解一些基本的浮点属性来回答,但是将问题标记为重复应该意味着它们是完全重复的。它不应用于在不提供答案的情况下转移广泛类别的问题。这个问题不是the purported original的重复问题。

标签: python numpy floating-point


【解决方案1】:

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

您展示的 Numpy 样本似乎使用八位十进制数字或九位有效数字。对于普通的 float32 值,从十进制转换引起的变化往往是被转换值的 0.00000003 倍左右(并且是转换值的两倍),因此它们在九位有效数字中可见。对于普通的 float64 值,从十进制转换引起的变化往往约为该值的 0.0000000000000001 (10−16) 倍,因此它们太小而无法在九位有效数字中可见。

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

【讨论】:

  • 为了记录,这里是 NumPy 的输出而不是 Python 的输出。 NumPy 有自己的 float32float64 类型,有自己的字符串表示,独立于 Python 内置的 float 类型。打印数组时,NumPy 会四舍五入到一个固定的精度;我认为默认情况下它是 8 位有效数字(但可能记错了)。
猜你喜欢
  • 2021-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-15
  • 1970-01-01
  • 2020-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多