Numpy: np.left_shift e np.right_shift falham nos tipos escalares np.uint64 (Trac # 1931)

Criado em 20 out. 2012  ·  7Comentários  ·  Fonte: numpy/numpy

_Tíquete original http://projects.scipy.org/numpy/ticket/1931 em 2011-08-10 pelo usuário trac tlatorre, atribuído a desconhecido._

>>> np.uint64(5) << 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'left_shift' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule 'safe'
>>> np.uint64(5) >> 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'right_shift' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule 'safe'
00 - Bug numpy.core

Comentários muito úteis

A solução mais fácil é usar um número inteiro sem sinal para o turno:

np.uint64(5) << np.uint64(1)

Como @charris mencionou acima, o problema está na maneira como os dtypes são uniformizados. Não é tão trivial corrigir genericamente (consulte também # 5668), embora talvez os operadores de deslocamento possam ser especiais. (RP bem-vindo, embora, como disse, isso não seja trivial, mas requer um entendimento justo de como os loops internos nos ufucs são decididos ...)

Todos 7 comentários

_ @ charris escreveu em 13/

Isso ocorre porque o número de deslocamento é convertido em um tipo com sinal e não há nenhum tipo de inteiro com sinal grande o suficiente para conter um uint64. Os operadores de deslocamento precisam ter um caso especial, eles também podem falhar na Intel porque o hardware mascara os bits desnecessários, ou seja, para int32 apenas os 5 bits inferiores são examinados.

_trac usuário parejkoj escreveu em 2012-07-27_

Consegui codificar em torno disso com o seguinte lambda:

lshift = lambda x,s: np.uint64(x)*np.uint64(2**s)

Isso funciona, mas não é o ideal. Consertar isso em numpy seria muito útil.

já se passaram cinco anos ... não é uma questão importante? inteiros sem sinal não devem ter ambigüidade sobre deslocamentos.

A solução mais fácil é usar um número inteiro sem sinal para o turno:

np.uint64(5) << np.uint64(1)

Como @charris mencionou acima, o problema está na maneira como os dtypes são uniformizados. Não é tão trivial corrigir genericamente (consulte também # 5668), embora talvez os operadores de deslocamento possam ser especiais. (RP bem-vindo, embora, como disse, isso não seja trivial, mas requer um entendimento justo de como os loops internos nos ufucs são decididos ...)

A solução mais fácil é usar um número inteiro sem sinal para o turno:

np.uint64 (5) << np.uint64 (1)

... que funciona se você souber que está operando com números inteiros, mas se estiver usando código genérico (especialmente algo que já foi escrito em outro módulo e está fora do seu controle), como

def f(x):
    return x | (x >> 1)

então você não pode fazê-lo funcionar tanto em inteiros Python regulares quanto em tipos np.uint64.

Não estou tentando afirmar que isso é trivial (bem acima do meu conjunto de habilidades), mas acho que deve ser uma alta prioridade.

@ jason-s - Concordo que o problema é muito chato ... Infelizmente, não há tantos de nós tão bem versados ​​em como os ufuncs funcionam internamente ...

Talvez se pudesse, pelo menos, escalares de casos especiais para a mudança no método, no entanto, em vez de confiar na maquinaria ufunc geral. @charris : era isso que você tinha em mente (se você se lembra disso depois de 6 anos ;-).

Veja também # 8002.

Pessoalmente, se pudéssemos fazer tudo novamente, eu seria a favor de refazer todo o casting / coerção para que o casting numpy se comporte essencialmente como o casting C e siga o espírito do casting C para casos que não existem em C. as regras são meio estranhas e às vezes confusas (por exemplo, a conversão de uint64 + int64 em float64 ). Mas já discutimos muito isso na lista, parece difícil de mudar.

Quando me deparo com situações como essa (veja meu comentário lá), eu apenas envolvo cada valor em np.uint64 .

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

toddrjen picture toddrjen  ·  4Comentários

kevinzhai80 picture kevinzhai80  ·  4Comentários

Levstyle picture Levstyle  ·  3Comentários

perezpaya picture perezpaya  ·  4Comentários

manuels picture manuels  ·  3Comentários