我想知道为什么a - b
和a + (-b)
给予了相同的结果,但在numpy
中的类型不同:
import numpy as np
minuend = np.array(1, dtype=np.int64)
subtrahend = 1 << 63
result_minus = minuend - subtrahend
result_plus = minuend + (-subtrahend)
print(result_minus == result_plus) # True
print(type(result_minus)) # float64
print(type(result_plus)) # int64
字符串
为什么会这样?我在哪里可以读到它?
1条答案
按热度按时间kg7wmglp1#
关键是
1 << 63
不能用int64
类型表示,但-(1 << 63)
可以。这是一个病态的情况,来自于有符号整数如何以二进制(C2 representation)表示。一方面,Numpy将
subtrahend
(1 << 63
)转换为uint64
值,因为int64
太小,无法保存该值。另一方面,
-subtrahend
是由CPython计算的,因此它会产生一个包含-(1 << 63)
的纯Python整数。然后Numpy将该值转换为int64
值(因为此类型足够大,可以容纳该值)。Numpy只在内部对相同类型的数组进行操作。涉及不同类型的二进制操作会导致数组提升(从C语言继承而来,主要是因为Numpy是用C编写的):Numpy转换输入数组的类型,因此目标二进制操作是有意义的,也是安全的(没有溢出,以在病态情况下可能损失精度为代价)。
在这种情况下,当执行减法时,Numpy选择将最终数组存储在
float64
数组中,因为对uint64
和int64
数组进行二进制操作可能会导致溢出(无符号整数太大,无法存储在有符号整数中,负有符号整数无法表示为无符号整数)。当执行加法时,两个数组/值是相同类型的(即int64
),因此不需要任何提升,结果数组的类型为int64
。下面是一个方法来看看:
字符串