3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【C++】組み込み型の使用バイト数と最小/最大値の調べ方

Last updated at Posted at 2021-09-04

はじめに

C++では組み込み型は基本型(fundamental type)とも呼ばれます。実はこの組み込み型、同じintなのにCPUのビット数やコンパイラによって確保されるバイト数が異なり最大値最小値も変わってしまうということが起こります。

この記事では、使用バイト数と最小/最大値を調べる方法を紹介します。

調査方法

次のコードを書きました。
手元で走らせるだけでバイト数と最小/最大値がわかります。

dump_bound.cpp
# include <iostream>
# include <limits>

# define dump(var) cout << string(#var) << ": " << var << endl;

using namespace std;

int main(void) {
  dump(sizeof(char));
  dump((int)numeric_limits<char>::min());
  dump((int)numeric_limits<char>::max());
  dump(sizeof(unsigned char));
  dump((int)numeric_limits<unsigned char>::min());
  dump((int)numeric_limits<unsigned char>::max());
  dump(sizeof(short));
  dump(numeric_limits<short>::min());
  dump(numeric_limits<short>::max());
  dump(sizeof(unsigned short));
  dump(numeric_limits<unsigned short>::min());
  dump(numeric_limits<unsigned short>::max());
  dump(sizeof(int));
  dump(numeric_limits<int>::min());
  dump(numeric_limits<int>::max());
  dump(sizeof(unsigned int));
  dump(numeric_limits<unsigned int>::min());
  dump(numeric_limits<unsigned int>::max());
  dump(sizeof(long));
  dump(numeric_limits<long>::min());
  dump(numeric_limits<long>::max());
  dump(sizeof(unsigned long));
  dump(numeric_limits<unsigned long>::min());
  dump(numeric_limits<unsigned long>::max());
  dump(sizeof(long long));
  dump(numeric_limits<long long>::min());
  dump(numeric_limits<long long>::max());
  dump(sizeof(unsigned long long));
  dump(numeric_limits<unsigned long long>::min());
  dump(numeric_limits<unsigned long long>::max());
  dump(sizeof(float));
  dump(numeric_limits<float>::min());
  dump(numeric_limits<float>::max());
  dump(sizeof(double));
  dump(numeric_limits<double>::min());
  dump(numeric_limits<double>::max());
  dump(sizeof(long double));
  dump(numeric_limits<long double>::min());
  dump(numeric_limits<long double>::max());
  return 0;
}

以下の環境で実行しました。

% g++-11 --version
g++-11 (Homebrew GCC 11.1.0_1) 11.1.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

結果

環境に依存するので参考程度に!!
浮動小数点の最小値は"最小の正の値"を表しています。

基本型 使用バイト数 最小値 最大値
char 1 -128 127
unsigned char 1 0 255
short 2 -32768 32767
unsigned short 2 0 65535
int 4 -2147483648 2147483647
unsigned int 4 0 4294967295
long 8 -9223372036854775808 9223372036854775807
unsigned long 8 0 18446744073709551615
long long 8 -9223372036854775808 9223372036854775807
unsigned long long 8 0 18446744073709551615
float 4 1.17549e-38 3.40282e+38
double 8 2.22507e-308 1.79769e+308
long double 16 3.3621e-4932 1.18973e+4932
生出力
% ./a.out    
sizeof(char): 1
(int)numeric_limits<char>::min(): -128
(int)numeric_limits<char>::max(): 127
sizeof(unsigned char): 1
(int)numeric_limits<unsigned char>::min(): 0
(int)numeric_limits<unsigned char>::max(): 255
sizeof(short): 2
numeric_limits<short>::min(): -32768
numeric_limits<short>::max(): 32767
sizeof(unsigned short): 2
numeric_limits<unsigned short>::min(): 0
numeric_limits<unsigned short>::max(): 65535
sizeof(int): 4
numeric_limits<int>::min(): -2147483648
numeric_limits<int>::max(): 2147483647
sizeof(unsigned int): 4
numeric_limits<unsigned int>::min(): 0
numeric_limits<unsigned int>::max(): 4294967295
sizeof(long): 8
numeric_limits<long>::min(): -9223372036854775808
numeric_limits<long>::max(): 9223372036854775807
sizeof(unsigned long): 8
numeric_limits<unsigned long>::min(): 0
numeric_limits<unsigned long>::max(): 18446744073709551615
sizeof(long long): 8
numeric_limits<long long>::min(): -9223372036854775808
numeric_limits<long long>::max(): 9223372036854775807
sizeof(unsigned long long): 8
numeric_limits<unsigned long long>::min(): 0
numeric_limits<unsigned long long>::max(): 18446744073709551615
sizeof(float): 4
numeric_limits<float>::min(): 1.17549e-38
numeric_limits<float>::max(): 3.40282e+38
sizeof(double): 8
numeric_limits<double>::min(): 2.22507e-308
numeric_limits<double>::max(): 1.79769e+308
sizeof(long double): 16
numeric_limits<long double>::min(): 3.3621e-4932
numeric_limits<long double>::max(): 1.18973e+4932

こちらの表とも一致してそうです。
https://atcoder.jp/contests/apg4b/tasks/APG4b_y?lang=ja#:~:text=%E4%B8%BB%E3%81%AA%E7%AC%A6%E5%8F%B7%E4%BB%98%E3%81%8D%E6%95%B4%E6%95%B0%E5%9E%8B

余談: intやlongを使うよりuint64_tで統一したほうが楽そう?

AtCoderではint??_t系が推奨されています。これらの型はC++11から導入され、固定長です。

int??_t系やuint??_t系以外については、環境によっては上の表と異なることがあります。
(略)
たくさんあってどう使い分けるのか分からなくなるかもしれませんが、 int??_t系やuint??_t系を使うことをおすすめします。 極端な話ですが、使用するメモリ量をそこまで気にしないのであれば全てint64_t型かuint64_t型を使ってしまうという手もあります。
https://atcoder.jp/contests/apg4b/tasks/APG4b_y?lang=ja

プロダクトでも整数型を64bitに統一できると、キャストについて事故を起こすリスクや開発コストを減らせそうでいいですね。

ただし、int64_t に罠があるという意見もあるそうです。

参考

intの最大値と最小値の調べ方
https://stackoverflow.com/questions/1855459/maximum-value-of-int
数値型
https://atcoder.jp/contests/apg4b/tasks/APG4b_y?lang=ja
Fixed width integer types
https://en.cppreference.com/w/cpp/types/integer

3
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?