Cython retorna 0 para expressão que deve ser avaliada em 0,5?


8

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-gnue language_levelestá definido como 3.

O que é essa bruxaria?


Quais configurações de compilação você está usando e para qual versão do Python você está compilando? O seu language_levelconjunto para a versão Python que você está compilando? (A inconsistência provavelmente é um bug, mesmo se houver uma incompatibilidade entre a language_levelsua versão e a sua versão do Python, mas essas informações são importantes para diagnosticar o problema.)
user2357112 suporta Monica

Editou a pergunta para incluir esses detalhes. 10x
iTayb

DavidW, está perfeitamente correto, você pode tentar usar o 1.0 para fazê-lo flutuar: print (2 ** -1.0)
Fanto

Respostas:


4

É 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

__Pyx_pow_long(2, -1L)

onde __Pyx_pow_longé uma função do tipo static 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

 print(2. ** (-1))

Como um comentário geral sobre a escolha do design: pessoas do mundo C geralmente esperam int operator intretornar um int, 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.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.