abs(-2147483648)の結果は-2147483648ですよね?それは受け入れられないようです。
printf("abs(-2147483648): %d\n", abs(-2147483648));
出力:
abs(-2147483648): -2147483648
標準は約を言いますabs()
:
、、、および関数
abs
は、整数の絶対値を計算します。結果を表現できない場合、動作は未定義です。labs
llabs
j
また、符号付き整数の2の補数表現は対称ではないため、結果を実際に表すことはできません。考えてみてください...に32ビットがある場合、からへの232の異なる値が得int
られます。これは偶数の値です。したがって、0が1つしかない場合、0より大きい値の数を0より小さい値の数と同じにすることはできません。したがって、値が-の正の値はありません。INT_MIN
INT_MAX
INT_MIN
INT_MIN
したがって、受け入れられないのはabs(INT_MIN)
、プラットフォームでの呼び出しです。
負の数は通常、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再び
同じことが元の質問にも当てはまります
2147483648はINT_MAX
実装よりも大きいため、abs(-2147483648)
未定義です。
これは、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をご覧ください。
これを試して
printf("abs(-2147483648): %u\n", abs(-2147483648));