パール
print 2 % -18;
-->
-16
Tcl
puts [expr {2 % -18}]
-->
-16
しかし、VBScript
wscript.echo 2 mod -18
-->
2
違いはなぜですか?
ここではウィキペディアの回答がかなり役に立ちます。
簡単にまとめると、任意の整数を次のように定義できます。
a = qn + r
これらの文字はすべて整数であり、
0 <= |r| < |n|。
ほとんどすべてのプログラミング言語では、(a/n) * n + (a%n) = a が必要です。したがって、モジュラスの定義は、ほぼ常に整数除算の定義に依存します。負の数による整数除算には、2/-18 = 0 または 2/-18 = -1 の 2 つの選択肢があります。あなたの言語にどちらが当てはまるかに応じて、通常は % 演算子が変わります。
これは、2 = (-1) * -18 + (-16) および 2 = 0 * -18 + 2 であるためです。
Perl の場合、状況は複雑です。マニュアル ページには次のように記載されています。 " そのため、use integer がスコープ内にある場合、Perl (C など) のいずれかのオプションを選択できます。use integer がスコープ内にない場合、マニュアルには「 $b が負の場合、 $a % $b は $a から $a よりも小さくない $b の最小倍数を引いた値になります (つまり、結果は以下またはゼロに等しい)」
ウィキペディアの「モジュロ演算」ページでは、非常によく説明されています。微妙ではあるが重要な間違いを犯す可能性があるため、ここではこれ以上改善しようとはしません。
問題は、「剰余」または「モジュラス」をさまざまな方法で定義でき、さまざまな言語がさまざまな実装オプションを選択していることです。
数値と除数 (そのうちの 1 つは負) を除算した後、商 * 除数 + 剰余 = 数値となるように、それらを商と剰余に分ける少なくとも 2 つの方法があります。商を負の無限大に丸めることができます。またはゼロに向かって。
多くの言語は 1 つだけを選択します。
Common Lispが両方を提供していることを指摘せずにはいられません。
もちろん、Pythonは明示的に通知します
>>> divmod(2,-18)
(-1, -16)