【问题标题】:NumPy casts lower precision to higher precision in floating point arithmeticNumPy 在浮点运算中将较低的精度转换为较高的精度
【发布时间】:2017-12-22 12:53:22
【问题描述】:

毫无疑问,其他(也许是所有)语言都是这种情况,但我只在 Python 中进行过测试。我的问题是这样的: 对两个不同精度的值进行算术运算时,为什么 NumPy 会以精度最高的值的 dtype 返回结果?

例如

import numpy as np

single = np.array([[1, 2, 3], [4, 5, 6]], np.float32)  
double = np.array([[1, 2, 3], [4, 5, 6]], np.float64)

diff = single-double

print "single data type -", single.dtype  
print "double data type -", double.dtype  
print "diff data type -", diff.dtype

产量:

单一数据类型 - float32
双数据类型 - float64
diff 数据类型 - float64

据我了解浮点精度,diff 表示的额外后半部分不准确。在这种情况下,将结果转换为最高精度而不是最低精度的原因是什么?

【问题讨论】:

    标签: python numpy precision


    【解决方案1】:

    这称为类型强制,至少在 NumPy 中,它总是会强制转换为精度更高的类型,因为这样您就不会意外丢失精度并且不会溢出。

    例如(关于“溢出”)强制转换为float64 它(排序)有效:

    >>> np.float64(1e40) - np.float32(1)
    1e40
    

    但如果它强制转换为float32,你会得到:

    >>> np.float64(1e40).astype(np.float32) - np.float32(1)
    inf
    

    那是因为最大的float323.4028235e+38

    >>> np.finfo(np.float32)
    finfo(resolution=1e-06, min=-3.4028235e+38, max=3.4028235e+38, dtype=float32)
    

    【讨论】:

      【解决方案2】:

      这是因为数值计算中的一个原理,称为灾难性抵消。

      考虑两个浮点数之间的稍微小一点的例子。 3.0000900 - 3.000,如果将其转换为小数点后 4 位,或者在您的情况下转换为 4 个字节,我们的结果值为 0。但是这些值实际上并不相同!我刚才演示的这种现象称为灾难性取消。由于截断甚至四舍五入,我们基本上会丢失信息。

      为了避免这种情况,这些操作的结果总是被类型转换为更精确的类型,因为丢失的信息是最小的。

      【讨论】:

        【解决方案3】:

        答案大多来自mathematics and the types of numbers

        types64 的类型包含 types32 的集合,就像实数(浮点数)的类型包含整数类型一样。

        无论何时执行计算,如果将结果集映射到更大的数据容器(整数类型 64 而不是 32)中,则可以保证提供令人满意的结果,但不能保证在映射时不会截断结果可能较短的容器中的一组值,这意味着产生无效的结果。

        float 和 int 也一直如此。在大多数语言中,将浮点数与整数相乘得到浮点数,因为浮点数(实数)在数学上可以包含整数,而反之则不成立(整数类型不包含实数)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-02-03
          • 2023-04-05
          • 2013-04-16
          • 2011-11-17
          • 2018-03-11
          • 2015-06-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多