被除数に負の数をとる場合のPythonの剰余演算規則
この投稿は最終更新日から1年以上経過しています
Pythonの剰余演算(モジュロ)で
>>>-1 % 4
3
という結果が返ってくるのはどうしてだろう?
(x // yの注)整数の除算とも呼ばれます。結果の型は整数型とは限りませんが、結果の値は整数です。結果は常に負の無限大の方向に丸められます: 1//2 は 0 、 (-1)//2 は -1 、 1//(-2) は -1 、そして (-1)//(-2) は 0 です。
% (剰余: modulo) 演算は、第一引数を第二引数で除算したときの剰余になります。数値引数はまず共通の型に変換されます。右引数値がゼロの場合には ZeroDivisionError 例外が送出されます。引数値は浮動小数点でもよく。例えば 3.14%0.7 は 0.34 になります (3.14 は 4*0.7 + 0.34 だからです)。剰余演算子は常に第二引数と同じ符号 (またはゼロ) の結果になります; 剰余演算の結果の絶対値は、常に第二引数の絶対値よりも小さくなります。
切り捨て除算演算と剰余演算は、恒等式: x == (x//y)*y + (x%y) の関係にあります。切り捨て除算や剰余はまた、組み込み関数 divmod(): divmod(x, y) == (x//y, x%y) とも関係しています。
要点は次の3つ。
- 整数除算の端数処理は負の無限大方向へ丸める
- x == (x // y) * y + (x % y)が成り立つ
- 剰余演算結果の符号は(0を除き)除数と同じものになる
負の無限大への丸めで端数処理される整数除算の影響は剰余演算にも及び、自然とその値は定まる。
-1%4の場合なら
- -1 // 4 = -1 (切り捨てて0とはせず、-∞方向へ丸める)
- -1 == -1 * 4 + (-1 % 4)
- 符号は除数4と同じで+
となり、3が返されるわけだ。
剰余演算で数値をローテーション
上記規則によって、被除数が負の数でも剰余演算を利用した数のローテーションを実現できる。
>>>[i % 4 for i in range(-10, 10)]
[2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1]