3

2 つの正の整数 i と j の場合、(-i)/j が -(i/j) と等しくない可能性はありますか? これが可能かどうかはわかりません...ビットに関するものか、char型のオーバーフローか何かだと思いましたが、見つかりません。何か案は?

4

2 に答える 2

12

C99 より前では、負のオペランドの除算が実装定義であるため可能です。代数除算またはゼロ方向への丸めが可能です。C99 では、ゼロ方向に丸めるように定義されています。

たとえば、C89 では が許可されますが(-1)/2 == -1、C99 では が必要(-1)/2 == 0です。すべての場合において、-(1/2) == 0.

于 2013-02-14T06:35:32.360 に答える
3

符号なし整数を使用して i と j を表す場合、実際に可能です (正の整数と言いましたよね? :P)。

たとえば、次のプログラムの出力は(-i)/j 2147483647 -(i/j) 0、私の Intel 64 ビット OSX マシンにあります (unsigned int は 32 ビット長です)。

#include <stdio.h>


int main()
{
  unsigned int i = 1;
  unsigned int j = 2;
  printf("(-i)/j %u -(i/j) %u\n", (-i)/j, -(i/j));

  return 0;
}

アセンブラを見るとnegl、否定を計算するために intel 命令が使用されています。2 の補数neglを実行します。2 の補数の結果が符号なしの値として解釈されると、不一致が発生します。しかし、単に私の言葉を鵜呑みにしないでください。以下に例を示します。

たとえば、8 ビット ワードを想定し、i=1 および j=2 の場合

バイナリ形式: i=00000001 j=00000010

-(i/j) = twos_complement(00000001/00000010) = twos_complement(00000000) = 00000000

-(i)/j = twos_complement(00000001)/00000010 = 11111111 / 00000001 = 1111111 (10 進数で 127)

符号なし表現によって引き起こされる不一致は、C99 コンパイラを使用している場合でも発生します。@R が述べているように、負の数による除算は実装定義であるため、c99 より前のコンパイラでも別の不一致が発生する可能性があります。

于 2013-02-14T06:36:52.813 に答える