私の友人は、「mod」と「remainder」には違いがあると言いました。
もしそうなら、CとC ++のそれらの違いは何ですか?'%'は、Cで「mod」または「rem」のいずれかを意味しますか?
係数と剰余には違いがあります。例えば:
-21
mod4
はです。3
_-21 + 4 x 6
3
しかし、の余りで与えることで-21
割った。4
-5
-1
正の値の場合、違いはありません。
「%」は C の「mod」または「rem」を意味しますか?
C では%
、剰余1です。
...、
/
演算子の結果は、小数部分が破棄された代数商です ... (これは、「ゼロへの切り捨て」と呼ばれることがよくあります。) C11dr §6.5.5 6演算子のオペランドは
%
整数型でなければなりません。C11dr §6.5.5 2演算子の結果は
/
、第 1 オペランドを第 2 オペランドで割った商です。%
演算子の結果は剰余... C11dr §6.5.5 5
「mod」と「remainder」の違いは何ですか?
C では、ユークリッド除算やその他の moduloで使用される整数モジュラス関数など、「mod」または「modulo」演算子/関数は定義されていません。
C は剰余を定義します。
%
オペレーターごとの「剰余」をユークリッドの「mod」と比較してみましょう。
「ユークリッド mod」は、が負のa%b
場合の C の操作とは異なります。a
// a % b, the remainder after an integer division that truncates toward 0.
7 % 3 --> 1
7 % -3 --> 1
-7 % 3 --> -1
-7 % -3 --> -1
「Mod」またはユークリッド除算のモジュロ。結果は常に 0 または正です。
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 の整数剰余に似ています。
関数はの
fmod
浮動小数点剰余を計算しx/y
ます。C11dr §7.12.10.1 2
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」の議論とはほとんど関係がありません。
[2020年12月編集]
すべてのケースで適切な機能が必要な場合は、modulo_Euclidean()
1) が検出されmod(x,0)
、2) UB が良好でなくてもmodulo_Euclidean2(INT_MIN, -1)
. 完全に定義された動作を持つ modulo の 4 つの異なる実装に触発されました。
int modulo_Euclidean2(int a, int b) {
if (b == 0) TBD_Code(); // perhaps return -1 to indicate failure?
if (b == -1) return 0; // This test needed to prevent UB of `INT_MIN % -1`.
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;
}
1 C99 より前では、C の定義%
は依然として除算の剰余/
でしたが、負の商を「ゼロに向かって切り捨てる」のではなく切り捨てることができました。C89 の整数除算で異なる値が得られるのはなぜですか? を参照してください。. したがって、C99 より前のコンパイルでは、%
コードはユークリッド除算 "mod" のように機能します。上記modulo_Euclidean()
は、この代替の古い学校の残りの部分でも機能します。
数学では、剰余演算の結果はユークリッド除算の余りです。ただし、他の規則も可能です。コンピュータと計算機には、数値を格納および表現するさまざまな方法があります。したがって、モジュロ演算の定義は、プログラミング言語および/または基礎となるハードウェアに依存します。
7 modulo 3 --> 1
7 modulo -3 --> -2
-7 modulo 3 --> 2
-7 modulo -3 --> -1