2017-04-06 173 views
0

比較:NumPy按位「和」失敗int32&long,但不是long&int32;爲什麼?

>>> import numpy; numpy.int32(-1) & 0xFFFFFFFF00000000 

TypeError: ufunc 'bitwise_and' not supported for the input types, and the inputs 
could not be safely coerced to any supported types according to the casting rule ''safe'' 

有了這個:

>>> import numpy; 0xFFFFFFFF00000000 & numpy.int32(-1) 

18446744069414584320L 

都如預期或其中至少有一個錯誤的工作?爲什麼會發生?

+0

雙方產生類型錯誤與numpy的1.11.1和1.12.1。 – kennytm

+0

對於1.6.2,第一個給出了'18446744069414584320L',但是第二個:'TypeError:不支持的操作數類型爲&:'long'和'numpy.int32'。 –

+0

@kennytm:不是我在1.12.1上看到的...你在Windows上嗎? – Mehrdad

回答

1

不同之處在於調用了對象的__and____rand__方法。通常,左邊的表達式爲__and__,稱爲第一個。如果它返回NotImplemented,則右手錶達式將有機會(並且將調用__rand__)。

在這種情況下,numpy.int32已經決定它不可能是「相與」用長 - 至少不是很長,其價值是什麼上面可以通過本機類型來表示......

然而,根據在您的實驗中,python的long很樂意「和」numpy.int32 - 或者,您的numpy版本可能不對__and__對稱執行__rand__。這也可能是依賴於Python的版本(例如,如果你的python版本決定返回一個值而不是NotImplemented)。

在我的電腦,更沒有工作:

Python 2.7.12 |Continuum Analytics, Inc.| (default, Jul 2 2016, 17:43:17) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
Anaconda is brought to you by Continuum Analytics. 
Please check out: http://continuum.io/thanks and https://anaconda.org 
>>> import numpy 
>>> numpy.__version__ 
'1.11.2' 

但是我們可以看到的是什麼使用下面的腳本調用:

import sys 
import numpy 

class MyInt32(numpy.int32): 
    def __and__(self, other): 
     print('__and__') 
     return super(MyInt32, self).__and__(other) 

    def __rand__(self, other): 
     print('__rand__') 
     return super(MyInt32, self).__and__(other) 


try: 
    print(MyInt32(-1) & 0xFFFFFFFF00000000) # Outputs `__and__` before the `TypeError` 
except TypeError: 
    pass 

try: 
    print(0xFFFFFFFF00000000 & MyInt32(-1)) # Outputs `__rand__` before the `TypeError` 
except TypeError: 
    pass 

sys.maxint & MyInt32(-1) # Outputs `__rand__` 
print('great success') 

(sys.maxint + 1) & MyInt32(-1) # Outputs `__rand__` 
print('do not see this') 
+0

你可能還想嘗試'import numpy; print(numpy.int32(1)&0xABCD1234EFL)'btw ...這個長度也超出了32位範圍。 – Mehrdad

+0

@Mehrdad - 是的,這很有趣。它可能會把'int64'都轉換成。在某些時候,沒有一種快速的方法來執行'&'使用本地類型,這可能是'numpy'拒絕執行計算的地方。 – mgilson

+0

你知道預期的行爲是什麼嗎?這是我們應該依靠在未來版本中工作(或不工作)的東西嗎? – Mehrdad

相關問題