私は C の初心者です。私は最近、2's Complement
負の数を表す他の方法と、それ2's complement
が最も適切な理由について学びました。
私が聞きたいのは、例えば、
int a = -3;
unsigned int b = -3; //This is the interesting Part.
さて、int型の変換について
標準は次のように述べています。
6.3.1.3 符号付きおよび符号なし整数
整数型の値が _Bool 以外の別の整数型に変換される場合、その値が新しい型で表現できる場合、その値は変更されません。
それ以外の場合、新しい型が符号なしの場合、値が新しい型の範囲内になるまで、新しい型で表現できる最大値よりも 1 多い値を繰り返し加算または減算することによって、値が変換されます。
-3
で表すことができないため、最初の段落は使用できませんunsigned int
。
したがって、段落 2 が有効になり、unsigned int の最大値を知る必要があります。limits.hでUINT_MAXとして見つけることができます。この場合の最大値は であるため、計算は次のとおりです。4294967295
-3 + UINT_MAX + 1 = -3 + 4294967295 + 1 = 4294967293
現在4294967293
、バイナリ11111111 11111111 11111111 11111101
と-3
2の補数形式は11111111 11111111 11111111 11111101
本質的に同じビット表現であるため、符号なしintに割り当てようとしている負の整数に関係なく、常に同じになります.したがって、符号なし型は冗長ではありません.
これは標準によると未定義の動作であることはわかっていますprintf("%d" , b)
が、合理的でより直感的な方法ではありません。負が として表されている場合、表現は同じ2's Complement
であり、それが現在のものであり、使用される他の方法はまれであり、おそらく将来の開発ではありません.
したがって、 int と言う型が 1 つしかない場合、符号ビットint x = -1
を%d
チェックし、符号ビットが である場合は負の数を出力1
し、%u
常にプレーン 2 進数 (ビット) をそのまま解釈します。を使用しているため、加算と減算は既に処理されてい2's complement
ます。ですから、これはより直感的で単純な方法ではありません。