259

Cプログラムでは、以下の操作を試みていました(動作を確認するためだけに)

 x = 5 % (-3);
 y = (-5) % (3);
 z = (-5) % (-3); 

printf("%d ,%d ,%d", x, y, z); 

(2, -2 , -2)gccのように出力されました。毎回良い結果を期待していました。モジュラスが負になることはありますか? 誰でもこの動作を説明できますか?

4

12 に答える 12

217

C99では、いつa/b表現可能であるかを要求しています。

(a/b) * b + a%bは等しくなければならないa

これは論理的には理にかなっています。右?

これが何につながるか見てみましょう:


例A5/(-3)-1

=> (-1) * (-3) + 5%(-3) =5

5%(-3)これは、が2の場合にのみ発生する可能性があります。


例B(-5)/3-1

=> (-1) * 3 + (-5)%3 =-5

これは、次の場合にのみ発生する可能性(-5)%3があります-2

于 2012-07-30T11:43:34.550 に答える
204

%Cの演算子はモジュロ演算子ではなく、剰余演算子です。

モジュロ演算子と剰余演算子は、負の値に関して異なります。

剰余演算子では、結果の符号は被除数 (分子) の符号と同じですが、モジュロ演算子では、結果の符号は除数 (分母) と同じです。

C では、%操作を次のように定義してa % bいます。

  a == (a / b * b) + a % b

/向かって切り捨てられた整数除算0。これは、モジュロ演算子ではなく剰余演算子として0定義する (負の無限大に向かってではなく) に向かって行われる切り捨てです。%

于 2012-07-30T11:50:50.140 に答える
10

他の回答はC99以降で説明されています。負のオペランドを含む整数の除算は常にゼロに向かって切り捨てられます

C89では、結果が上方向または下方向に丸められるかどうかは実装定義であることに注意してください。すべての標準で(a/b) * b + a%b等しいため、負のオペランドを含む結果も C89 で実装定義されます。a%

于 2015-06-17T07:02:26.890 に答える
2

モジュロ演算の結果は分子の符号に依存するため、 yzに対して-2が得られます。

これがリファレンスです

http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_14.html

整数除算

このセクションでは、整数除算を実行するための関数について説明します。GNU Cでは「/」演算子は常にゼロに向かって丸められるため、これらの関数はGNUCライブラリでは冗長です。ただし、他のC実装では、「/」は負の引数で異なる方法で丸められる場合があります。divとldivは、商をゼロに丸める方法を指定するので便利です。余りは分子と同じ符号を持っています。

于 2012-07-30T11:42:40.230 に答える