Por alguma razão, o Cython está retornando 0 em uma expressão matemática que deve ser avaliada em 0,5:
print(2 ** (-1)) # prints 0
Curiosamente, misture variáveis e funcionará conforme o esperado:
i = 1
print(2 ** (-i)) # prints 0.5
Vanilla CPython retorna 0,5 para ambos os casos. Estou compilando 37m-x86_64-linux-gnu
e language_level
está definido como 3
.
O que é essa bruxaria?
python
python-3.x
cython
iTayb
fonte
fonte
language_level
conjunto para a versão Python que você está compilando? (A inconsistência provavelmente é um bug, mesmo se houver uma incompatibilidade entre alanguage_level
sua versão e a sua versão do Python, mas essas informações são importantes para diagnosticar o problema.)Respostas:
É porque ele está usando C ints em vez de inteiros Python, para que ele corresponda ao comportamento C em vez do Python. Estou relativamente certo de que isso costumava ser documentado como uma limitação em algum lugar, mas não consigo encontrá-lo agora. Se você deseja denunciá-lo como um bug, acesse https://github.com/cython/cython/issues , mas suspeito que seja uma troca deliberada de velocidade por compatibilidade.
O código é traduzido para
onde
__Pyx_pow_long
é uma função do tipostatic CYTHON_INLINE long __Pyx_pow_long(long b, long e)
.A maneira mais fácil de corrigir isso é alterar um / ambos os números para serem um número de ponto flutuante
Como um comentário geral sobre a escolha do design: pessoas do mundo C geralmente esperam
int operator int
retornar umint
, e essa opção será mais rápida. O Python tentou fazer isso no passado com o comportamento de divisão do Python 2 (mas inconsistentemente - o poder sempre retornava um número de ponto flutuante).O Cython geralmente tenta seguir o comportamento do Python. No entanto, muitas pessoas estão usando a velocidade para que eles também tentem voltar a operações rápidas tipo C, especialmente quando as pessoas especificam tipos (já que essas pessoas querem velocidade). Acho que o que aconteceu aqui é que ele foi capaz de inferir os tipos automaticamente e, por isso, assumiu o padrão de comportamento em C. Eu suspeito que, idealmente, ele deve distinguir entre tipos especificados e tipos que são inferidos. No entanto, provavelmente também é tarde demais para começar a mudar isso.
fonte
Parece que o Cython está inferindo incorretamente o tipo de dados final
int
e nãofloat
quando apenas números estão envolvidosO código a seguir funciona conforme o esperado:
Consulte este link para uma discussão relacionada: https://groups.google.com/forum/#!topic/cython-users/goVpote2ScY
fonte