web-dev-qa-db-ja.com

「mod」と「remainder」の違いは何ですか?

私の友人は、「mod」と「remainder」には違いがあると言いました。

もしそうなら、CとC++の違いは何ですか? 「%」はCの「mod」または「rem」を意味しますか?

113
songhir

モジュラスと剰余には違いがあります。例えば:

-21 mod 4は、3-21 + 4 x 6であるため、3です。

ただし、-214で割ると、-5-1の残りが与えられます。

正の値の場合、違いはありません。

120
David Schwartz

「%」はCの「mod」または「rem」を意味しますか?

Cでは、%remainderです。1

...、/演算子の結果は、小数部分が破棄された代数の商です...(これは、しばしば「ゼロへの切り捨て」と呼ばれます。)C11dr§6.5.56

%演算子のオペランドは整数型でなければなりません。 C11dr§6.5.52

/演算子の結果は、第1オペランドを第2オペランドで除算した商です。 %演算子の結果はremainder... C11dr§6.5.55


「mod」と「remainder」の違いは何ですか?

Cは、 ユークリッド除算 または その他のモジュロ で使用される整数モジュラス関数などの「mod」を定義しません。 「ユークリッドmod」は、aが負の場合、Cのa%b操作とは異なります。

 // a % b
 7 %  3 -->  1  
 7 % -3 -->  1  
-7 %  3 --> -1  
-7 % -3 --> -1   

ユークリッド除算としてのモジュロ

 7 modulo  3 -->  1  
 7 modulo -3 -->  1  
-7 modulo  3 -->  2  
-7 modulo -3 -->  2   

モジュロコードの候補:

int modulo_Euclidean(int a, int b) {
  int m = a % b;
  if (m < 0) {
    // m += (b < 0) ? -b : b; // avoid this form: it is UB when b == INT_MIN
    m = (b < 0) ? m - b : m + b;
  }
  return m;
}

浮動小数点に関する注意:double fmod(double x, double y)は、 "fmod"と呼ばれますが、ユークリッドの除算 "mod"とは異なりますが、C整数剰余と同様です。

fmodfunctionsは、x/yの浮動小数点剰余を計算します。 C11dr§7.12.10.12

fmod( 7,  3) -->  1.0  
fmod( 7, -3) -->  1.0  
fmod(-7,  3) --> -1.0  
fmod(-7, -3) --> -1.0   

曖昧さ回避 :Cにも同様の名前の関数double modf(double value, double *iptr)があり、引数値を整数部分と小数部分に分割します。各部分は引数と同じ型と符号を持ちます。これは、名前の類似性を除き、ここでの「mod」の説明とはほとんど関係ありません。


1 C99より前は、Cの%の定義は依然として除算のremainderでしたが、/は「ゼロに切り捨てるのではなく、負の商を切り捨てることができました。 「。 C89で整数除算の値が異なるのはなぜですか? を参照してください。したがって、C99以前のコンパイルでは、%コードはユークリッドの除算「mod」のように動作できます。上記のmodulo_Euclidean()は、この代替のオールドスクールの残りでも動作します。

36
chux

モジュラスは、参照しているモジュラー算術では、残された値、または算術除算後に残った値です。これは一般的に剰余として知られています。 %は、正式にはC/C++の剰余演算子です。例:

7 % 3 = 1  // dividend % divisor = remainder

議論のために残されているのは、この%操作に対する負の入力をどのように扱うかです。最新のCおよびC++は、除数入力の符号に関係なく、結果の符号が常に被除数入力と一致するであるこの演算の符号付き剰余値を生成します。

3
user487158