整数型の最大値と最小値

こんにちは、めのんです!

整数型の最大値と最小値は本当は昨日投稿しようと思っていたんですけど、時間が取れずに今日になってしまいました。
もともとのスケジュールでは、今日ロケールをやって明日ワイド文字の解説という流れでした。
ワイド文字は週末でないと難しいと思いますのでリスケジュールが必要ですね。

と、いきなり言い訳から始まってしまいましたが、気持ちを切り替えていきたいと思います。

整数型の表現範囲は処理系定義

Cではどの整数型の表現範囲も処理系定義になります。
PHPでも整数型の表現範囲はプラットフォームやバージョンによって異なりますので同じですね。
ただ、Cにはたくさんの整数型があるので話がややこしくなっています。

あらためてCにどんな整数型があるのか挙げてみます。

符号付き整数型 符号無し整数型 その他
signed char unsigned char char
short unsigned short
int unsigned int
long unsigned long
long long unsigned long long
_Bool
列挙型

たくさんありますね。

このうち表現範囲が処理系によらないのは_Bool型だけです。
それ以外はすべて表現範囲が処理系定義になります。

符号付き整数型の内部表現

Cの規格では、符号付き整数型の最小値は-最大値かそれ以下になっています。
何らかのプログラミング経験がある方は「あれっ?」と思われるかもしれませんね。

普通、符号付き整数型というのはマイナスの値を表すのに2の補数表現を使います。
けれども、Cでは3種類の表現方法が許されています。

  • 符号と絶対値(sign and magnitude)
  • 2の補数(two’s complement)
  • 1の補数(one’s complement)

このうち、どの表現方法が採用されるかは処理系定義になります。

現実には2の補数表現しかないと考えてもほぼ問題はないと思います。
ただ、2の補数表現だからといって、符号付き整数型の最小値が-最大値-1になるかというと違います。
符号ビットが1でそれ以外がすべて0の状態を「トラップ表現(trap representation)」とみなすことも可能だからで、この場合は最小値が-最大値になります。

char型について

Cのchar型が1バイトだということは規格で定義されています。
けれども、1バイトが何ビットかは処理系定義になります。
また、signedもunsignedも付かないchar型が符号付きか符号無しかも処理系定義です。

こういった事情があって、さらにはさきほど解説した内部表現のこともあって、char型の表現範囲は処理系によってかなり異なります。
内部表現が2の補数以外の処理系に実際で出会う機会はまずありませんが、それに比べて1バイトが8バイトではない処理系に出会う可能性はずっと高いと思います。

整数型の表現範囲を表すマクロ

Cの整数値の表現範囲は処理系定義ですので、何らかの方法で自分が使っている処理系の表現範囲を知りたいですよね。
そのためのマクロが「limits.h」ヘッダで定義されています。

最大値と最小値を表すマクロ

基本的には、符号付き整数型は最大値と最小値が、符号無し整数型は最大値がマクロで定義されています。
符号無し整数型に最小値のマクロがないのは0に決まっているからです。
char型は符号付きか符号無しかが処理系定義ですので、符号無しの場合でも最小値が定義されています。

それでは、最初に掲載した整数型一覧に対応する形でマクロの一覧を挙げてみますね。

符号付き整数型 符号無し整数型 その他
SCHAR_MAX, SCHAR_MIN UCHAR_MAX CHAR_MAX, CHAR_MIN
SHRT_MAX, SHRT_MIN SHRT_MIN
INT_MAX, INT_MIN UINT_MAX
LONG_MAX, LONG_MIN ULONG_MAX
LLONG_MAX, LLONG_MIN ULLONG_MAX

_Bool型と列挙型に対応するマクロはありません。
この理由はわかりますよね。

ざっと見ていただければわかるように、マクロ名のルールはおわかりいただけるかと思います。
注意が必要なのは、short型はSHORT_ではなくSHRT_だということ(「O」がない)、long long型はLONG_LONG_ではなくLLONG_だということぐらいでしょうか。

整数型の表現範囲については、最小限保証される範囲が規格で定められているので、本来であればそれについてもここで解説したいのですけど、長くなりそうなので別の機会にゆずることにします。

その他のマクロ

「limits.h」ヘッダには最大値と最小値以外のマクロが2つ定義されています。
せっかくですのでそれらについても解説しておくことにします。

CHAR_BIT

マクロ「CHAR_BIT」はchar型のビット数、つまり(その処理系における)1バイトのビット数に定義されます。
通常は8に定義されています。

MB_LEN_MAX

マクロ「MB_LEN_MAX」は、その処理系における多バイト文字の最大バイト数になります。
最近の処理系はUTF-8に対応するものが多いと思いますので、4か6に定義されているんじゃないかなと思います。

ちなみに、Unicodeの場合はUTF-8の最大バイト数は4ですけどISO/IEC 10646では6ですので、このあたりに微妙な違いが出てきますね。


今回の解説は以上となります。
リスケジュールすることにしましたので、整数の表現範囲の話題をもう少し深掘りしようと思います。
どうぞご期待ください!