実験プログラム
#include<bits/stdc++.h>
using namespace std;
//予想
short s=32767;//2^15-1
unsigned short us=65535;//2^16-1
int i=2147483647;//2^31-1
unsigned int ui=4294967295;//2^32-1
long l=2147483647;//2^31-1
unsigned long ul=4294967295;//2^32-1
long long ll=(1LL<<63)-1;//2^63-1
unsigned long long ull=(1LL<<64)-1;//2^64-1
int main() {
//予想値
cout<<s<<endl;
cout<<us<<endl;
cout<<i<<endl;
cout<<ui<<endl;
cout<<l<<endl;
cout<<ul<<endl;
cout<<ll<<endl;
cout<<ull<<endl;
cout<<endl;
//オーバーフローするかどうかの実験
s+=1;
us+=1;
i+=1;
ui+=1;
l+=1;
ul+=1;
ll+=1;
ull+=1;
cout<<s<<endl;
cout<<us<<endl;
cout<<i<<endl;
cout<<ui<<endl;
cout<<l<<endl;
cout<<ul<<endl;
cout<<ll<<endl;
cout<<ull<<endl;
cout<<endl;
//実際値
cout<<SHRT_MAX<<endl;
cout<<USHRT_MAX<<endl;
cout<<INT_MAX<<endl;
cout<<UINT_MAX<<endl;
cout<<LONG_MAX<<endl;
cout<<ULONG_MAX<<endl;
cout<<LLONG_MAX<<endl;
cout<<ULLONG_MAX<<endl;
cout<<endl;
//オーバーフローするかどうかの実験
s=SHRT_MAX+1;
us=USHRT_MAX+1;
i=INT_MAX+1;
ui=UINT_MAX+1;
l=LONG_MAX+1;
ul=ULONG_MAX+1;
ll=LLONG_MAX+1;
ull=ULLONG_MAX+1;
cout<<s<<endl;
cout<<us<<endl;
cout<<i<<endl;
cout<<ui<<endl;
cout<<l<<endl;
cout<<ul<<endl;
cout<<ll<<endl;
cout<<ull<<endl;
return 0;
}
実験結果
$gpp data_type.cpp && ./a.out
data_type.cpp:10:23: warning: integer overflow in expression of type 'long long int' results in '9223372036854775807' [-Woverflow]
long long ll=(1LL<<63)-1;//2^63-1
~~~~~~~~~^~
data_type.cpp:11:30: warning: left shift count >= width of type [-Wshift-count-overflow]
unsigned long long ull=(1LL<<64)-1;//2^64-1
^~
data_type.cpp: In function 'int main()':
data_type.cpp:53:15: warning: unsigned conversion from 'int' to 'short unsigned int' changes value from '65536' to '0' [-Woverflow]
us=USHRT_MAX+1;
^
data_type.cpp:54:12: warning: integer overflow in expression of type 'int' results in '-2147483648' [-Woverflow]
i=INT_MAX+1;
^
data_type.cpp:56:13: warning: integer overflow in expression of type 'long int' results in '-9223372036854775808' [-Woverflow]
l=LONG_MAX+1;
^
data_type.cpp:58:15: warning: integer overflow in expression of type 'long long int' results in '-9223372036854775808' [-Woverflow]
ll=LLONG_MAX+1;
^
32767
65535
2147483647
4294967295
2147483647
4294967295
9223372036854775807
18446744073709551615
-32768
0
-2147483648
0
2147483648
4294967296
-9223372036854775808
0
32767
65535
2147483647
4294967295
9223372036854775807
18446744073709551615
9223372036854775807
18446744073709551615
-32768
0
-2147483648
0
-9223372036854775808
0
-9223372036854775808
0
|データ型|最大値|
|---|---|---|
|short|32,767|
|unsigned short|65,535|
|int|2,147,483,647|
|unsigned int|4,294,967,295|
|long|9,223,372,036,854,775,807|
|unsigned long|18,446,744,073,709,551,615|
|long long|9,223,372,036,854,775,807|
|unsigned long long|18,446,744,073,709,551,615|
考察
- shortは2バイトなので最大値は$2^{15}-1$で32,767でした。約$3*10^4$です。
- unsigned shortも2バイトなので最大値は$2^{16}-1$で65,535でした。約$6*10^4$です。
- intは4バイトなので最大値は$2^{31}-1$で2,147,483,647でした。約$2*10^9$です。
- unsigned intも4バイトなので最大値は$2^{32}-1$で4,294,967,295でした。約$4*10^9$です。
- longとlong long、unsigned longとunsigned long longは同じでした(たぶん64bit環境のため)。なので、long longを使う必要はありません。longで大丈夫です。longは約$910^{18}$です。unsigned longは約$110^{19}$とです。
- メモリ使用量を重要視する場合はデータが扱う範囲にできるだけフィットしたデータ型を使う方がいいです。
- $10^4$以下ならshortを使います。
- $10^9$以下ならintを使います。
- $10^{18}$以下ならlongを使います。
- $10^{19}$以下ならunsigned longを使います。
- 競技プログラミングでは思考を省略するために、負の整数も使う場合はlong、0および自然数を扱う場合はunsigned longを使うのがよさそうです。
- 多倍長整数のcpp_intを使えば正負すら気にせず使えます(ただし配列の添字に使えません><)。