25

abs(-2147483648)の結果は-2147483648ですよね?それは受け入れられないようです。

printf("abs(-2147483648): %d\n", abs(-2147483648));

出力:

abs(-2147483648): -2147483648
4

5 に答える 5

30

標準は約を言いますabs()

、、、および関数absは、整数の絶対値を計算します。結果を表現できない場合、動作は未定義です。labsllabsj

また、符号付き整数の2の補数表現は対称ではないため、結果を実際に表すことはできません。考えてみてください...に32ビットがある場合からへの232の異なる値が得intられます。これは偶数の値です。したがって、0が1つしかない場合、0より大きい値の数を0より小さい値の数と同じにすることはできません。したがって、値が-の正の値はありません。INT_MININT_MAXINT_MININT_MIN

したがって、受け入れられないのはabs(INT_MIN)、プラットフォームでの呼び出しです。

于 2012-06-28T13:30:49.000 に答える
18

負の数は通常、2進数の補数で表されます。

正から負に変換するには、ロジックが使用されます

x -> not(x)+1

8ビット演算の場合

01111111bは127で、-127は
10000000b + 1=10000001bになります

反対方向に-12710000001bは
01111110b+1=01111111bになります

-128はどうですか?

-128は10000000bであり、8ビットの符号付き演算に128がないため、正の対応物はありません。

10000000-> 01111111 + 1=10000000および-128再び

同じことが元の質問にも当てはまります

于 2012-06-28T14:23:38.180 に答える
10

2147483648はINT_MAX実装よりも大きいため、abs(-2147483648)未定義です。

于 2012-06-28T11:17:19.790 に答える
5

これは、GNUGlibcソースコードのabs.cのコードです。

/* Return the absolute value of I.  */
int
DEFUN(abs, (i), int i)
{
  return(i < 0 ? -i : i);
}

したがって、abs(-2147483648)は-(-2147483648)を返します。x86では、この2つの命令によって実装されます

movl    $-2147483648, %eax
negl    %eax

negl命令は、次のように実装されます。num = 0-num; sbbは、次のように実装されます。宛先からソースを減算し、キャリーフラグが設定されている場合はさらに1を減算します。したがって、abs(-2147483648)(hexは0x80000000)->-(-2147483648)-> 0-(-2147483648)は最終的に(0x80000000)になります。

ネイルインストラクションの詳細については、http: //zsmith.co/intel_n.html#negをご覧ください。

sbb命令の詳細については、http://web.itu.edu.tr/kesgin/mul06/intel/instr/sbb.htmlをご覧ください。

于 2012-06-28T13:14:49.633 に答える
-5

これを試して

printf("abs(-2147483648): %u\n", abs(-2147483648));
于 2012-06-28T11:10:40.207 に答える