Python のモジュロは紛らわしいです。
Python では、%
演算子は剰余を計算しています。
>>> 9 % 5
4
でも:
>>> -9 % 5
1
結果はなぜ1
ですか?ではありません-4
か?
Python のモジュロは紛らわしいです。
Python では、%
演算子は剰余を計算しています。
>>> 9 % 5
4
でも:
>>> -9 % 5
1
結果はなぜ1
ですか?ではありません-4
か?
-10%5は0です。つまり、-10は5で均等に除算されます。
-9%5が-4ではない理由を尋ねると、答えは1と-4の両方が正解である可能性があるということです。これは、-9を5で割った値によって異なります。もちろん、-9を5で割った値は1.8ですが、これは整数の除算であり、Python 3では//で表されるため、ここでは//を使用して、これが話している整数の除算であることを明確にします。
負の数を使わない方が簡単です。
9 // 5は1です。つまり、9から5を1回だけ引くことができ、残りは4です。しかし、もう一度9から5を引くと、残りは-1になります。
したがって、9 // 5が2の場合、-1は9%5に対する正解です。
Python 9では、// 5は1です。これは、Pythonの整数除算がフロア除算であるためです。つまり、常に切り捨てられます。切り上げた場合、9 // 5は2になり、9%5は-1になります。
ここで、負の数を使用する場合を見てみましょう。-9を5で割ると-2になります。フロア分割であるため、常に切り捨てられます。つまり、残りは1です。したがって、-9%5は-1であり、-4ではありません。
これは、Python が整数除算を丸める方法に関係しています。
数学的には、任意の int x および y に対して常に次のことが成り立つ必要があります。
x == (x // y) * y + x % y
したがって、このことから言えることは、
x % y == x - (x // y) * y
ここで、Python は整数除算をゼロではなく負の無限大に丸めることを思い出してください。たとえば、-9 // 5 は -1 ではなく -2 を返します。このロジックでは、-9 % 5 = 1 が得られます。
次のように考えてください。
0 % 5 は 0
1 % 5 は 1
じゃあ…後ろ向きにしたら?
-1 % 5 は 4 でなければなりません
-2 % 5 は 3 でなければなりません
等々。
これに従うと、-9 % 5 が 1 であることがわかります。
注: プログラミング言語と % の実装によっては、異なる結果が得られる場合があります。これは、プログラマーが % の負の数を処理する方法に同意していないためです。
整数では、そのような商を常に選択できるとは限りませんquotient * divisor == dividend
。product
が に等しくない場合は、よりもわずかに小さくするか、 よりもわずかに大きくdividend
するかを常に選択する必要があります。との合計が になります。それが です。いずれにせよ、被除数と積は近くなければなりません。つまり、剰余の絶対値は除数の絶対値よりも小さくなければなりません。dividend
dividend
product
remainder
dividend
remainder
divisor
が正の場合、増加products
としてquotients
増加します。divisor
が負の場合、減少products
はquotients
増加します。前者の場合、製品は下から、後者の場合、製品は上から進みます。Python では、どちらの場合も、が次の可能な に到達したquotient
ときにのみ次のものが取得され、製品が進むのと同じように進みます。その前は、次の に対応するための変更のみであり、常に被除数の変更と同じ方向に進み、ゼロで途切れることはありません。この規則は Python では普遍的であり、常に保持されます。dividend
product
remainder
dividend
これは、この選択が行われた理由ではありませんが、何が起こるか (つまり、結果が何であるか、どのような結果が期待されるか) を示しています。