Pythonで、負の数に関して奇妙な動作を見つけました。
>>> -5 % 4
3
誰かが何が起こっているのか説明できますか?
Pythonで、負の数に関して奇妙な動作を見つけました。
>>> -5 % 4
3
誰かが何が起こっているのか説明できますか?
..., -9, -5, -1, 3, 7, ...
math.fmod
して、CまたはJavaと同じ動作を得ることができます。
回答:
CやC ++とは異なり、Pythonのモジュロ演算子(%
)は常に分母(除数)と同じ符号の数値を返します。あなたの式は3をもたらします。
(-5)/ 4 = -1.25->フロア(-1.25)= -2
(-5)%4 =(-2×4 + 3)%4 = 3。
非負の結果の方が役立つことが多いため、Cの動作よりも選択されます。例は、平日を計算することです。今日が火曜日(2日目)の場合、N日前の曜日は何日ですか?Pythonでは次のように計算できます
return (2 - N) % 7
場合はCで、N ≥3、私たちは、無効な番号である負の数を取得し、我々は手動7を追加することによって、それを修正する必要があります。
int result = (2 - N) % 7;
return result < 0 ? result + 7 : result;
(さまざまな言語で結果の符号がどのように決定されるかについては、http://en.wikipedia.org/wiki/Modulo_operatorを参照してください。)
グイドヴァンロッサムからの説明は次のとおりです。
http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html
基本的に、a / b = qで、余りがrの場合、関係b * q + r = aおよび0 <= r <bが保持されます。
a
、それらは否定的、肯定的b
です。それは常に真実でabs(r) < b
あり、彼らはiffをceilしr <= 0
ます。
整数の除算と負の数のmodを処理する最良の方法はありません。a/b
同じ大きさと反対の符号があればいいのですが(-a)/b
。a % b
確かにモジュロbであるといいでしょう。本当に欲しいa == (a/b)*b + a%b
ので、最初の2つは互換性がありません。
どちらを維持するかは難しい質問であり、双方に議論があります。CおよびC ++は整数の除算をゼロ(so a/b == -((-a)/b)
)に丸めますが、Pythonはそうではないようです。
指摘されているように、Pythonモジュロは、他の言語の規則に対して理にかなった例外を作ります。
これにより、特に//
整数除算演算子と組み合わせて使用すると、負の数がシームレスに動作します%
。モジュロがよくあるように(math。divmodのように):
for n in range(-8,8):
print n, n//4, n%4
生産:
-8 -2 0
-7 -2 1
-6 -2 2
-5 -2 3
-4 -1 0
-3 -1 1
-2 -1 2
-1 -1 3
0 0 0
1 0 1
2 0 2
3 0 3
4 1 0
5 1 1
6 1 2
7 1 3
%
常にゼロまたは正を出力します*//
常に負の無限大に向かって丸めます* ...右のオペランドが正である限り。一方11 % -10 == -9
python、モジュロ演算子は、このように動作します。
>>> mod = n - math.floor(n/base) * base
したがって、結果は(あなたの場合):
mod = -5 - floor(-1.25) * 4
mod = -5 - (-2*4)
mod = 3
一方、C、JAVA、JavaScriptなどの他の言語では、floorの代わりに切り捨てが使用されます。
>>> mod = n - int(n/base) * base
その結果:
mod = -5 - int(-1.25) * 4
mod = -5 - (-1*4)
mod = -1
Pythonでの丸めについてさらに情報が必要な場合は、こちらをお読みください。
Pythonの分割もCとは異なることにも言及する価値があります。
>>> x = -10
>>> y = 37
Cでは結果を期待します
0
Pythonのx / yとは何ですか?
>>> print x/y
-1
%はモジュロです-余りではありません!Cのx%yは
-10
Pythonが生成します。
>>> print x%y
27
あなたはCのように両方を得ることができます
分裂:
>>> from math import trunc
>>> d = trunc(float(x)/y)
>>> print d
0
そして残り(上からの除算を使用):
>>> r = x - d*y
>>> print r
-10
この計算はおそらく最速ではありませんが、xとyの任意の符号の組み合わせに対して機能し、Cと同じ結果を達成し、さらに条件付きステートメントを回避します。