1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PythonAdvent Calendar 2024

Day 22

長年Pythonを使っていても…演算子優先順位でバグった話

Posted at

はじめに

私の遭遇したバグを紹介します。
初見だと、なかなか気づくことが難しいとおもうので、こんなことがあるんだと知っておくといいかもしれません。
結構、原因がわからずに悩みました。

本題の前に

私の遭遇したバグは、整数の割り算//に関係しているので、先に、整数の割り算について説明しておきます。
'//'演算子は、整数の割り算を行う演算子です。

割り算の結果は、整数で返されます。

例えば、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//30-(X//3) → 0-3-3 です

まとめ

単項演算子の-は、先に評価されるので気を付けましょう

これを機会に、演算子の優先順位をおさらいしておこう。

Pythonのドキュメントは、ここです

1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?