計算機 -1 mod 26 = 25 で、C または Java でどのようになりますか-1 % 26 == -1
。電卓のようにそれを解くプログラムが必要です。両者に違いはありますか?
3 に答える
両方の答え (25 と -1) が有効です。異なるシステムには異なる規則があるというだけです。
私が(数学で)最も一般的に見ているものは次のとおりです。
quotient = floor(x / y)
remainder = x - quotient * y
floor()
は負の無限大に向かって丸めます。
これは、電卓が提供する規則です。(Mathematica もこの規則を使用します.)
ほとんどのプログラミング言語が使用していると私が思うものは次のとおりです。
quotient = integerpart(x / y)
remainder = x - quotient * y
whereintegerpart()
は (float -> integer) キャストと同じです。(ゼロに向かって丸めます)
一部の規則では、剰余をオペランドの 1 つと同じ符号に保ちます。
同じことが分周器の符号にも当てはまります。異なる規則は異なります。
"どうして ... ?"
モジュロ演算には 2 つの一般的な定義があります。Java が 1 つ (「被除数と同じ符号」) を選択し、電卓が別のものを実装します。おそらく「除数と同じ符号」ですが、確認するにはいくつかの実験を行う必要があります。
実際、モジュロ演算に関するウィキペディアのページには、さまざまなプログラミング言語で使用される演算子の 4 つの異なる定義が示されています。(また、一部のプログラミング言語では、セマンティクスが異なる 2 つの演算子が提供されます。)
C の場合、定義は、話している C 標準のバージョンによって異なります。ISO C 1999 では、剰余演算子は Java と同じ定義に従います。C 標準の以前のバージョンでは、 のセマンティクス%
は実装に依存します。
「両者に違いはありますか?」
明らかにあります!
「電卓のように解けるプログラムが必要です。」
自由に書いてください:-)。
しかし、Java で「除数と同じ符号」形式のモジュラスを取得する方法を知りたい場合は、次の 1 つの方法があります。
int otherModulus = (a % b) + (a < 0 ? b : 0); // works for b > 0.
int otherModulus = (a % b) + // works for b != 0
(b > 0 ? (a < 0 ? b : 0) : (a > 0 ? -b : 0));
負のオペランドを使用するモジュロ演算は言語によって異なり、駆動する言語の定義次第です。Javaでは、ModulusはRemainderに似ています。
一般に、負の入力に対して負の数を取得する場合は、次を使用できます。
int r = x % n;
if (r > 0 && x < 0)
{
r -= n;
}
または、負の入力で負の数を返す言語を使用していて、正の数を好む場合:
int r = x % n;
if (r < 0)
{
r += n;
}
したがって、目的の結果として必要なものに基づいて、計算する言語に依存するのではなく、適切な実装を使用することをお勧めします。
また、Javaの場合の結果は、JLSのセクション15.17.3- 剰余演算子%で正式に説明されていることに注意してください。それらはそこで動機を与えます(a%bは(a / b)* b +(a%b)がaに等しいようなものでなければなりません)が、結果をそうするのはJLSにそのセクションを含めることです。