【问题标题】:numpy exponentiation with ** on integer array vs float array在整数数组与浮点数组上使用 ** 进行 numpy 取幂
【发布时间】:2020-09-07 12:36:13
【问题描述】:

为什么** 对浮点数组和整数数组进行操作会有区别?

  1. ** 在整数数组和浮点数组上的作用有何不同?
  2. 这是某种机器精度的舍入问题吗?
  3. 为什么它只是一个数组的问题,而不是当我输入它时?

MWE:为什么f(ns) 不等于f(fs)

import numpy as np
def f(x):
    a = +x**5
    b = +x**6 
    return a-b

ns = np.array([60])   #integers
fs = np.array([60.])  #floats

print(ns)
print(fs)

print(f(ns))
print(f(fs))

print(int(60)**5- int(60)**6)
print(60.**5 - 60.**6)

导致

[60]
[60.]

[1366240256]
[-4.58784e+10]

-45878400000
-45878400000.0

【问题讨论】:

  • 确切的数据类型是什么?
  • 假设您在 Windows 或其他默认整数大小为 32 位的平台上运行。仔细查看np.array([60])**6。整数计算溢出最大 32 位整数并“环绕”为负值。 (在默认整数为 64 位的平台上,任何人都可以通过np.array([60], dtype=np.int32)**6 看到效果。)
  • print(f(ns)) 在我的 64 位 linux 系统上提供 [-45878400000]

标签: python arrays numpy precision exponentiation


【解决方案1】:

因为np.int32int 是不同的东西。也就是说,numpy 整数数组的元素不是 Python 整数。

在 Python 中,int 是一个任意长度的整数。你可以计算123**45,得到一个90+位的整数,正好是123**45

在 numpy 中,数组元素是标准的 32 位或 64 位(有时是 8 或 16 位)整数,算术运算符是标准 CPU 算术。在这种情况下,数字几乎肯定是有符号或无符号的 32 位。所以它用 32 位整数计算 60**6。由于它不适合 32 位,因此结果类似于 606 模 232

【讨论】:

    【解决方案2】:

    对于 int 类型,您的系统默认为 np.int32,因此这是一个溢出问题。您需要使用 np.int64 才能使其正常工作。观察:

    In [3]: ns = np.array([60],dtype=np.int32)
    
    In [4]: f(ns)
    Out[4]: array([1366240256], dtype=int32)
    
    In [5]: ns = np.array([60],dtype=np.int64)
    
    In [6]: f(ns)
    Out[6]: array([-45878400000])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-20
      • 2017-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多