計算機の中の%
は何をしているのですか?何をしているのかがわかりません。
例えば、4 % 2
は0に等しいようですが、どうやって計算するのですか?
%(modulo)演算子は、第1引数を第2引数で除算した余りを出力します。数値の引数は、まず共通の型に変換されます。右の引数がゼロの場合、ZeroDivisionError例外が発生します。モジュロ演算子は常に2番目のオペランドと同じ符号(またはゼロ)を持つ結果を生成し、結果の絶対値は2番目のオペランドの絶対値よりも厳密に小さくなります[2]。
http://docs.python.org/reference/expressions.html より引用
**例1:**********************。
6%2は
0` と評価されます。なぜなら、6 を 2 で割っても余ることはないからです(3回)。
例2:7%2は
1と評価されます。これは 7 を 2 で割っても
1` の余りがあるからです(3回)。
つまり,要約すると,割り算の余りを返すか,余りがなければ0
を返すということです。 つまり、6%2
は、6を2で割ったときの余りを求めるという意味です。
x % yのような式は、
x ÷ yの余りと評価されます。まあ、技術的には、"reminder"ではなく、"modulus"なので、
%が余り演算子である他の言語と比較した場合、結果は異なるかもしれません。[いくつかの微妙な違いがあります](https://rob.conery.io/2018/08/21/mod-and-remainder-are-not-the-same/) (もし実用的な結果に興味があるなら、下記の "Why Python's Integer Division Floors" も参照してください)。 優先順位は演算子
/(除算)や
*` (乗算)と同じです。
>>> 9 / 2
4
>>> 9 % 2
1
%
は (非推奨の) 文字列補間演算子でもあります。したがって、自動型キャストを備えた言語 (PHP や JS など) から来ていて、'12' % 2 + 3
のような式が有効な場合は注意してください。
[Python 3へのアップデート]
ユーザーの n00p さんのコメントです。9/2はpythonでは4.5です。9/2はpythonでは4.5です。整数の割り算はこのようにしなければなりません。pythonでdivision(4)の後に何個の整数が残っているか教えて欲しい場合は、9/2/2のように整数分割しなければなりません。 正確に言うと、Python 2では整数分割がデフォルトでした(気にしてください、この答えはすでに学校に行っている私の息子よりも古く、当時は2.xが主流でした)。
$ python2.7
Python 2.7.10 (default, Oct 6 2017, 22:29:07)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4
>>> 9 // 2
4
>>> 9 % 2
1
現代のPythonでは 9 / 2
の結果は確かに 4.5
です。
$ python3.6
Python 3.6.1 (default, Apr 27 2017, 00:15:59)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4.5
>>> 9 // 2
4
>>> 9 % 2
1
[update]
ユーザーの dahiya_boy さんがコメントセッションで質問しました。
Q.** なぜ -11 % 5 = 4
となるのか説明してください - dahiya_boy さん
これはおかしいですよね?これをJavaScriptでやってみると。
> -11 % 5
-1
%
が "remainder" 演算子であるのに対し、Pythonでは "modulus" (クロック数学) 演算子であるためです。-11 % 5 = -1
ですが、pythonやrubyでは-11 % 5 = 4
となります。
その理由の半分はPaulo Scardine氏によって説明されていますが、残りの説明は以下の通りです。
JavaやiOSでは、%
は余りを表します。つまり、11 % 5を割ると、「商=2、余り=1」となり、11 % 5を割ると、「商=2、余り=1」となります。
swift iOSでのサンプルコードです。
[![enter image description here][1]][1].
しかし、pythonで話すと、クロックモジュラスが得られます。そして、それは以下の公式で動作します。
mod(a,n) = a - {n Floor(a/n)}` となります。
ということになります。
mod(11,5) = 11 - {5 Floor(11/5)} => 11 - {5 2}` となります。
ということで、mod(11,5)=1となります。
そして
mod(-11,5) = -11 - 5 Floor(11/5) => -11 - {5 * (-3)}となります。 つまり、mod(-11,5) = 4
となります。
python 3.0.でのサンプルコードです。
[![Enter image description here][2]][2].なぜPython'の整数分割フロアー
Pythonの整数除算が、C言語のように0に向かって切り捨てるのではなく、結果の階数を返す理由を説明してほしいと、今日(再び)聞かれました。
正の数については、驚くことではありません。
>>> 5//2
2
しかし、オペランドの1つが負の場合、結果はfloored、つまりゼロから離れて(負の無限大に向かって)丸められます。
>>> -5//2
-3
>>> 5//-2
-3
しかし、これには数学的な理由があります。整数の除算演算(//)とその兄弟であるモジュロ演算(%)が一緒になると、数学的に良い関係を満たします(すべての変数は整数)。
a/b = q with remainder r
以下のようになります。
b*q + r = a and 0 <= r < b
(aとbが>=0であると仮定して)。
負のaに対しても関係を伸ばしたい(bは正のまま)場合、2つの選択肢があります。qを0に向かって切り詰めると、rが負になり、不変量は0 <= abs(r) < そうでなければ、qを負の無限大に向かって階調を上げても、不変量は0 <= r < bのままです。
数学の数論では、数学者は常に後者の選択を好みます(例えば[Wikipedia][3]参照)。Pythonでも同じ選択をしました。なぜなら、aの符号が気にならないmodulo演算には興味深い応用例があるからです。POSIXのタイムスタンプ(1970年の開始からの秒数)を1日の時間に変換することを考えてみましょう。1日には24*3600=86400秒あるので、この計算は単純にt % 86400となります。しかし、1970年以前の時間を負の数で表現すると、"truncate towards zero"のルールでは意味のない結果になってしまいます。フロアルールを使えば、すべてうまくいきます。
他に思いついたのは、コンピュータグラフィックスのピクセル位置の計算です。他にもあると思います。
ところで、負のbについては、すべてが反転してしまい、不変量は次のようになります。
0 >= r > b.
では、なぜC言語ではこの方法を取らないのでしょうか?おそらく、C言語が設計された時点では、ハードウェアがこの方法を採用していなかったのでしょう。ハードウェアがこのようにしなかったのは、最も古いハードウェアでは、負の数は最近使われている2の補数表現ではなく、"sign + magnitude"として表現されていたからでしょう(少なくとも整数については)。私の最初のコンピュータはControl Data社のメインフレームで、整数にも浮動小数点にも1の補数が使われていました。60個の1のパターンはマイナスゼロを意味していました。
Pythonの浮動小数点のスケルトンがどこに埋もれているかを知っているTim Peters氏は、私がこのルールを浮動小数点モジュロに拡張したいと思っていることについて心配しています。彼の言う通り、xが非常に小さな負の数の場合、x%1.0のuncate-towards-negative-infinityルールは精度の低下を引き起こす可能性があります。しかし、それだけでは整数のモジュロを壊すことはできませんし、 // はそれと密接に結びついています。
追記。私は / の代わりに // を使っていることに注意してください -- これは Python 3 の構文であり、Python 2 でも整数の除算を実行していることを強調するために許可されています。Python 2の/演算子は、2つの整数演算子の場合、intとfloatまたは2つのfloatの場合とは異なる結果を返すので、曖昧なのです。しかし、それは全く別の話で、PEP238を参照してください。 となっています。 Posted by Guido van Rossum at 9:49 AM
モジュラス演算子は、通常、整数の剰余分割に使用されますが、Pythonでは浮動小数点数にも使用できます。
http://docs.python.org/reference/expressions.html
% (modulo) 演算子は、最初の引数を2番目の引数で割った余りを出力します。数値の引数は、まず共通の型に変換されます。右の引数がゼロの場合、ZeroDivisionError 例外が発生します。モジュロ演算子は常に2番目のオペランドと同じ符号(またはゼロ)を持つ結果を生成し、結果の絶対値は2番目のオペランドの絶対値よりも厳密に小さくなります[2]。