C++でデータ型の範囲を計算する方法
はじめに
C++には、int、char、doubleなど、さまざまなデータ型が用意されています。本記事では、これらのデータ型のサイズと、表現できる値の範囲をプログラムで求める方法を解説します。
データ型の範囲を求める仕組み
データ型のサイズはバイト単位で取得できるため、8を掛ければビット数に変換できます。ビット数をnとすると、符号付き整数の場合、最小値は「-2^(n-1)」、最大値は「2^(n-1) - 1」となります。一方、符号なし整数には負の数が存在しないため、範囲は「0」から「2^n - 1」までです。
サンプルコード
#include <iostream>
#include <cmath>
#define SIZE(x) sizeof(x) * 8 //サイズをビット単位で取得
using namespace std;
void getRange(string type, int n) {
if(type.compare("SIGNED") == 0) { //符号付きの場合、下限と上限を計算
int min = pow(2, n - 1);
int max = pow(2, n - 1) - 1;
cout << "Range from " << (-1) * min << " to " << max <<endl;
}else{ //符号なしの場合、0からの範囲を計算
int range = pow(2, n )-1;
cout << "Range from 0 to " << range << endl;
}
}
int main() {
cout << "For Signed int: ";
getRange("SIGNED", SIZE(int));
cout << "For Signed float: ";
getRange("SIGNED", SIZE(float));
cout << "For Unsigned int: ";
getRange("UNSIGNED", SIZE(unsigned int));
cout << "For Unsigned short: ";
getRange("UNSIGNED", SIZE(unsigned short int));
cout << "For Signed char: ";
getRange("SIGNED", SIZE(char));
}実行結果
For Signed int: Range from -2147483648 to 2147483647 For Signed float: Range from -2147483648 to 2147483647 For Unsigned int: Range from 0 to -2147483648 For Unsigned short: Range from 0 to 65535 For Signed char: Range from -128 to 127
結果の読み方と注意点
実行結果には、いくつか注意すべきポイントがあります。
- floatの結果について: sizeof(float)は4バイト(32ビット)なので、intと同じ「-2147483648 ~ 2147483647」が表示されます。しかし、floatはIEEE 754形式という独自の内部表現を持つため、実際に表現できる範囲は約±3.4×1038です。このコードの結果は、あくまでビット数を整数として計算したものだと理解しておきましょう。
- unsigned intの結果について: 32ビットの理論上の最大値「4294967295」は、int型で表現できる範囲を超えるため、オーバーフローが発生し「-2147483648」と表示されています。正しく表示するには、結果をlong long型などより大きな型で受け取る必要があります。
まとめ
このように、sizeofマクロでビット数を取得し、2のべき乗を用いた計算式を組み合わせることで、各データ型の理論上の範囲を簡単に求めることができます。ただし、浮動小数点型の実際の表現範囲や、大きな値を扱う際のオーバーフローには注意が必要です。
-
C++におけるPOD型とは?意味と特徴をわかりやすく解説
PODとは、C++における「Plain Old Data(プレーン・オールド・データ)」の略称です。POD型とは、メンバ変数のみを持ち、メンバ関数(メソッド)、コンストラクタ、デストラクタ、仮想関数などを一切持たない、シンプルなクラスや構造体のことを指します。POD型の条件クラスや構造体がPOD型とみなされるためには、主に以下のような要素を含んでいない必要があります。ユーザー定義のコンストラクタデストラクタコピー代入演算子などの特殊なメンバ関数仮想関数や仮想基底クラスコード例#include<iostream> using namespace std; // POD型の構造体 s
-
C++のsigned(符号付き)とunsigned(符号なし)キーワードとは?違いと使い方を解説
C++における符号付き・符号なしデータ型の基本C++では、すべての数値型に対して「符号付き(signed)」か「符号なし(unsigned)」かを指定できます。たとえば、int型を宣言する際に正の整数のみを扱うよう指定することも可能です。特別な指定がない場合、すべての整数型はデフォルトで符号付き(signed)として扱われます。つまり、正負どちらの値も保持できるということです。一方、unsignedキーワードを使用すると、符号を持たない変数を宣言できます。サンプルコード#include<iostream>using namespace std;int main() { &