はじめに
私の遭遇したバグを紹介します。
初見だと、なかなか気づくことが難しいとおもうので、こんなことがあるんだと知っておくといいかもしれません。
結構、原因がわからずに悩みました。
本題の前に
私の遭遇したバグは、整数の割り算//
に関係しているので、先に、整数の割り算について説明しておきます。
'//'演算子は、整数の割り算を行う演算子です。
割り算の結果は、整数で返されます。
例えば、10//3の結果は、3です。
気をつけないといけないのは、負の値の場合です。
小さい方に切り捨てられるので、-10//3の結果は、-4です。
-3 ←大きい方
-3.333333...
-4 ←小さいほう
プラスの場合とマイナスの場合で、結果が異なるんです。
どんなバグか
私のはまったバグは、次のようなものです
Xの値3で割った商の符号を変えたものを求める計算でした。
例えば、X=10の場合、-3 が想定してる答えです。
3で割って、符号を変える。
素直に
ans = -X//3
と書いてました。
これだと
ans == -4
となります。
解説
単項演算子の-
は、//
よりも優先順位が高いので、-X//3
は、(-X)//3
と解釈されます。
X=10の場合、
-X
の部分がが-10
なので、-10//3 = -4
で、-4
になります。
>>> X=10
>>> ans = (-X)//3
>>> ans
-4
正しく動作させるのは、
-(...)
とする必要がありました。
>>> X=10
>>> ans = -(X//3)
>>> ans
-3
おまけ
よく似た記述ですが、
ans = 0-X//3
の場合は、ans=-3
となります。
-
は、二項演算子なので、引き算よりも割り算が先に計算されます。
X=10の場合、0-X//3
→ 0-(X//3)
→ 0-3
→ -3
です
まとめ
単項演算子の-
は、先に評価されるので気を付けましょう
これを機会に、演算子の優先順位をおさらいしておこう。
Pythonのドキュメントは、ここです