変換のしくみ 例: char[-128, 127] のスコープ、unsigned char[0, 255] のスコープ
char x = -128;
unsigned char y = static_cast<unsigned char>(x);
cout<<y; //128
なぜ 0 ではないのですか?
変換のしくみ 例: char[-128, 127] のスコープ、unsigned char[0, 255] のスコープ
char x = -128;
unsigned char y = static_cast<unsigned char>(x);
cout<<y; //128
なぜ 0 ではないのですか?
符号付き型からの変換を含む符号なし算術演算はモジュラーであり、モジュラスは 2 n (n
はビット数) です。
が 8 ビットであると仮定するとchar
、-128 は 256 を法として 128 と一致します。それが変換の結果です。
更新: コメントに記載されているように、これは -128 が type の有効な値であると想定していますが、char
必ずしもそうとは限りません。char
の範囲は少なくとも[0..127]
、およびsigned char
少なくとも[-127..127]
です。
符号なし算術演算と符号なしへの変換は、モジュロ 2 Nで行われます。8 ビット文字なので、 N は 8、2 Nは 256 です。
-128 と 128 は 256 を法として合同です。
セクション 4.7 ( [conv.integral]
) にある実際のルールは次のとおりです。
- 宛先の型が符号なしの場合、結果の値は、ソースの整数と一致する最小の符号なし整数になります (モジュロ 2 n で、n は符号なしの型を表すために使用されるビット数です)。[ 注: 2 の補数表現では、この変換は概念的なものであり、ビット パターンに変更はありません (切り捨てがない場合)。— エンドノート]
- 宛先の型が符号付きの場合、宛先の型 (およびビットフィールド幅) で表現できる場合、値は変更されません。それ以外の場合、値は実装定義です。
変換は、スコープをバイアスするために +128 を追加するのではなく、同じビット パターンを別の方法で再解釈することによって機能します。詳細については、2 の補数を参照してください。