2017-04-06 179 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

相关问题