Cythonは、0.5に評価する必要がある式に対して0を返しますか?


8

何らかの理由で、Cythonは、0.5に評価されるはずの数式で0を返します。

print(2 ** (-1))  # prints 0

奇妙なことに、変数を混ぜると、期待どおりに機能します。

i = 1
print(2 ** (-i))  # prints 0.5

Vanilla CPythonはどちらの場合も0.5を返します。私はのため37m-x86_64-linux-gnuにコンパイルしlanguage_levelてい3ますが、に設定されています。

この魔術は何ですか?


どのコンパイル設定を使用していますか、どのPythonバージョンをコンパイルしていますか?あなたのあるlanguage_levelあなたがコンパイルしているPythonのバージョンに設定しますか?(language_levelお使いのPythonバージョンと不一致がある場合でも、この不一致はおそらくバグですが、この情報は問題の診断に重要です。)
user2357112はモニカ

これらの詳細を含むように質問を編集しました。10x
iTayb

DavidWそれはあなたが1.0を使ってそれをフロートさせるだけで試すことができる完全に正しいです:print(2 ** -1.0)
Fanto

回答:


4

これは、Pythonの整数ではなくCの整数を使用しているため、Pythonの動作ではなくCの動作と一致するためです。これは以前、制限として文書化されていたと確信していますが、今は見つかりません。バグとして報告したい場合は、https://github.com/cython/cython/issuesにアクセスしてください。ただし、これは互換性のために速度を意図的にトレードオフしたものではないかと思います。

コードは次のように変換されます

__Pyx_pow_long(2, -1L)

どこ__Pyx_pow_longタイプの関数ですstatic CYTHON_INLINE long __Pyx_pow_long(long b, long e)


それを修正する最も簡単な方法は、数値の1つまたは両方を浮動小数点数に変更することです

 print(2. ** (-1))

デザインの選択に関する一般的なコメントとして:Cの世界の人々は一般的にint operator intを返すことを期待してintおり、このオプションが最速になります。Pythonはこれまで、Python 2の除算動作でこれを試みました(ただし、一貫性がありません-パワーは常に浮動小数点数を返しました)。

Cythonは通常、Pythonの動作を追跡しようとします。ただし、多くの人がスピードのためにそれを使用しているので、特に人々がタイプを指定するとき(それらの人々はスピードを望んでいるため)、Cのような迅速な操作にフォールバックしようとします。ここで何が起こったのかは、型を自動的に推論することができたので、デフォルトでC動作になっていると思います。私は理想的には、指定されたタイプと推論されたタイプを区別する必要があると思います。ただし、それを変更し始めるのもおそらく遅すぎます。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.