崩壊した unsigned int ビット数 = signed int ビット数
2004年10月19日 C言語※JIS C 新JIS C の 1バイトのビット数は、必ずしも 8ビットではありませんが、説明の都合上「1バイト = 8ビット」と仮定して文章を書いています。
今まで、C言語の unsigned int ビット数と(符号ビットを含む) signed int ビット数は、必ず同じだ思っていました。たとえば、unsigned int が 4バイト 32ビットであれば、signed int も必ず 4バイト 32ビットだと思っていました。
が…新JIS C を見てみると、そうでは無かったのです。(^_^;
新JIS C では、unsigned char 以外の符号無し整数型のビットは、「(省略可能な)詰め物ビット」「値ビット」から構成されます。
例えば、図のような unsigned int 型が存在しえます。
[図1]
┏━━━━━━━━━━━━━━━━━━━━━┓
┃ unsigned int 型 (4バイト 32ビット) ┃
┣━━━━━━━┯━━━━━━━━━━━━━┫
┃詰め物ビット 2 │ 値ビット 30 ┃
┗━━━━━━━┷━━━━━━━━━━━━━┛
また、符号付き整数型のビットは、「(省略可能な)詰め物ビット」「符号 1ビット」「値ビット」から構成されます。
例えば、図のような signed int 型が存在しえます。
[図2]
┏━━━━━━━━━━━━━━━━━━━━━┓
┃ signed int 型 (4バイト 32ビット) ┃
┣━━━━━━━┯━━━━━━┯━━━━━━┫
┃詰め物ビット 1 │符号ビット 1 │値ビット 30 ┃
┗━━━━━━━┷━━━━━━┷━━━━━━┛
そして、符号付き整数型の値ビットのビット数は、対応する符号無し整数型の値ビット数以下でなければいけません。
つまり、unsigned int 型の値ビット数が 30 であれば、signed int 型の値ビット数は 30、もしくはそれ未満になります。
もう一度、これらを踏まえて[図1][図2]を見てください。
[図1]の unsigned int 型と[図2]の signed int 型は、対応する整数型の条件を満たしています。しかし、unsigned int 型のビット数は 30、(符号ビットを含む) signed int 型のビット数は 31 となり、ビット数が一致していません。
このような unsigned int 型と signed int 型を持つ処理系は、通常存在しないと思いますが、新JIS C 規格から外れたものではありません。
新JIS C において、詰め物ビットを除くビット数が一致するのは、符号付き型の値ビット数が、 符号無し型の値ビット数より 1 ビット少ない場合だけです。ビット数が一致するとは限らないのです。
【おまけ】
unsigned int signed int の詰め物ビット数や値ビット数等を表示する Cプログラムです。
なお、実際にコンパイルする場合は下記の作業を行う必要があります。
全角"<"文字を、全て半角文字に変更する。
全角">"文字を、全て半角文字に変更する。
全角","文字を、全て半角文字に変更する。
全角"%"文字を、全て半角文字に変更する。
全角スペース文字を、全て半角スペース文字に変更するか又は削除する。
--
#include <limits.h>
#include <stdio.h>
int main(void);
int main(void)
{
unsigned byte_size, bit_size, count_val;
byte_size = sizeof(unsigned);
for ( bit_size = 0, count_val = UINT_MAX; bit_size++, count_val >>= 1; );
printf("unsigned int 型の バイト数=%u 詰め物ビット数=%u 値ビット数=%u\n", byte_size, byte_size * CHAR_BIT - bit_size, bit_size);
byte_size = sizeof(int);
for ( bit_size = 0, count_val = INT_MAX; bit_size++, count_val >>= 1; );
printf("signed int 型の バイト数=%u 詰め物ビット数=%u 符号ビット数=1(固定) 値ビット数=%u\n", byte_size, byte_size * CHAR_BIT - (bit_size + 1), bit_size);
return 0;
}
--
今まで、C言語の unsigned int ビット数と(符号ビットを含む) signed int ビット数は、必ず同じだ思っていました。たとえば、unsigned int が 4バイト 32ビットであれば、signed int も必ず 4バイト 32ビットだと思っていました。
が…新JIS C を見てみると、そうでは無かったのです。(^_^;
新JIS C では、unsigned char 以外の符号無し整数型のビットは、「(省略可能な)詰め物ビット」「値ビット」から構成されます。
例えば、図のような unsigned int 型が存在しえます。
[図1]
┏━━━━━━━━━━━━━━━━━━━━━┓
┃ unsigned int 型 (4バイト 32ビット) ┃
┣━━━━━━━┯━━━━━━━━━━━━━┫
┃詰め物ビット 2 │ 値ビット 30 ┃
┗━━━━━━━┷━━━━━━━━━━━━━┛
また、符号付き整数型のビットは、「(省略可能な)詰め物ビット」「符号 1ビット」「値ビット」から構成されます。
例えば、図のような signed int 型が存在しえます。
[図2]
┏━━━━━━━━━━━━━━━━━━━━━┓
┃ signed int 型 (4バイト 32ビット) ┃
┣━━━━━━━┯━━━━━━┯━━━━━━┫
┃詰め物ビット 1 │符号ビット 1 │値ビット 30 ┃
┗━━━━━━━┷━━━━━━┷━━━━━━┛
そして、符号付き整数型の値ビットのビット数は、対応する符号無し整数型の値ビット数以下でなければいけません。
つまり、unsigned int 型の値ビット数が 30 であれば、signed int 型の値ビット数は 30、もしくはそれ未満になります。
もう一度、これらを踏まえて[図1][図2]を見てください。
[図1]の unsigned int 型と[図2]の signed int 型は、対応する整数型の条件を満たしています。しかし、unsigned int 型のビット数は 30、(符号ビットを含む) signed int 型のビット数は 31 となり、ビット数が一致していません。
このような unsigned int 型と signed int 型を持つ処理系は、通常存在しないと思いますが、新JIS C 規格から外れたものではありません。
新JIS C において、詰め物ビットを除くビット数が一致するのは、符号付き型の値ビット数が、 符号無し型の値ビット数より 1 ビット少ない場合だけです。ビット数が一致するとは限らないのです。
【おまけ】
unsigned int signed int の詰め物ビット数や値ビット数等を表示する Cプログラムです。
なお、実際にコンパイルする場合は下記の作業を行う必要があります。
全角"<"文字を、全て半角文字に変更する。
全角">"文字を、全て半角文字に変更する。
全角","文字を、全て半角文字に変更する。
全角"%"文字を、全て半角文字に変更する。
全角スペース文字を、全て半角スペース文字に変更するか又は削除する。
--
#include <limits.h>
#include <stdio.h>
int main(void);
int main(void)
{
unsigned byte_size, bit_size, count_val;
byte_size = sizeof(unsigned);
for ( bit_size = 0, count_val = UINT_MAX; bit_size++, count_val >>= 1; );
printf("unsigned int 型の バイト数=%u 詰め物ビット数=%u 値ビット数=%u\n", byte_size, byte_size * CHAR_BIT - bit_size, bit_size);
byte_size = sizeof(int);
for ( bit_size = 0, count_val = INT_MAX; bit_size++, count_val >>= 1; );
printf("signed int 型の バイト数=%u 詰め物ビット数=%u 符号ビット数=1(固定) 値ビット数=%u\n", byte_size, byte_size * CHAR_BIT - (bit_size + 1), bit_size);
return 0;
}
--
コメント