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;
}
--

コメント