プログラミング言語ごとにモジュラスが異なるのはなぜですか?
質問
Perl
print 2 % -18;
-<!> gt;
-16
Tcl
puts [expr {2 % -18}]
-<!> gt;
wscript.echo 2 mod -18
しかしVBScript
2
-<!> gt;
<*>違いはなぜですか
解決
ウィキペディアの回答は、ここでかなり役立ちます。
短い要約は、任意の整数を次のように定義できることです
a = qn + r
これらの文字はすべて整数であり、
0 <!> lt; = | r | <!> lt; | n |。
ほとんどすべてのプログラミング言語では、(a / n)* n +(a%n)= aが必要です。したがって、モジュラスの定義はほぼ常に整数除算の定義に依存します。負の数2 / -18 = 0または2 / -18 = -1による整数除算には2つの選択肢があります。あなたの言語に当てはまるものに応じて、通常%演算子が変更されます。
これは、2 =(-1)* -18 +(-16)および2 = 0 * -18 + 2であるためです。
Perlの場合、状況は複雑です。 マニュアルページの説明:<!> quot;整数を使用する場合はスコープ、<!> quot;%<!> quot; Cコンパイラで実装されているモジュラス演算子に直接アクセスできます。この演算子は、負のオペランドに対しては十分に定義されていませんが、より高速に実行されます。 <!> quot;したがって、整数の使用がスコープ内にある場合、Perlのいずれかのオプション(Cなど)を選択できます。 use integerがスコープ内にない場合、マニュアルには<!> quotと書かれています。 $ bが負の場合、$ a%$ bは、$ a-$ a以上の最小の倍数から$ aを引いたものです(つまり、結果はゼロ以下になります)。 <!>引用;
他のヒント
Wikipediaの <!> quot;モジュロ演算<!> quot; ページで非常によく説明されています。微妙ではあるが重要な間違いを犯す可能性が高いため、ここではこれ以上改善しようとはしません。
その難点は、<!> quot; remainder <!> quot;を定義できることです。または<!> quot; modulus <!> quot;さまざまな方法で、さまざまな言語がさまざまな実装オプションを選択しています。
数と除数の1つが負の数に分割された後、それらを商と剰余に分ける少なくとも2つの方法があります。商*除数+剰余=数:商を四捨五入できます負の無限大、またはゼロに向かって。
多くの言語が1つを選択します。
Common Lisp が提供していることを指摘することは避けられません両方。
もちろん、pythonは明示的に通知します
>>> divmod(2,-18)
(-1, -16)