大きな数の取り扱い
最終更新日02 Nov 2013 09:52
型 | サイズ | 最大値 | 10の何乗? | Java |
---|---|---|---|---|
unsigned short | 2byte | 0-65535 | $10^4$ | |
int | 4byte | -2147483648~2147483647 | $10^9$ | |
unsigned int | 4byte | 4294967295 | $10^9$ | |
unsigned long | 4byte | 4294967295 | $10^9$ | |
unsigned long long | 8byte | 18446744073709551615 | $10^{19}$ | |
double | 8byte | $1.79769e+308$ | $10^{308}$ | BigInteger,BigDecimal |
つまり、たいていのlargeの問題$10^{18}$やれという問題は、unsigned long longで解決できるってこと。
unsigned long long の別の表記
- ULONGLONG
- unsigned int64_t
整数対決★
正確な整数を扱った場合、double,float,intどれが一番表現力があるのか???型 | 数値 | 桁数 | 数値 |
---|---|---|---|
float | 9999999 | 7 | 9百万程度 |
double | 999999999999999 | 15 | 99兆程度 |
long | 9223372036854775807 | 19 | 9億2万兆程度 |
floatやdoubleはもちろん、もっと大きな数も表現することができるけど、決められた桁数以上の数値は勝手に四捨五入して下の桁の方を0で埋めてしまうのだ。
つまり、正確じゃないってこと。
大きな数の宣言の仕方
指数表現で書くとわかりやすいたとえば、300000000と書いて0が何個だっけーとなるよりも、3.E8と書いたほうが0が何個かわかりやすいですね
C++ | Java | |
---|---|---|
300000000 | 3.E8 | 3.e8 |
0.003 | 3.E-3 | 3.e-3 |
const int LARGE_NUM=3.E8;//=300000000 13*10e+03
printfの書式
C/C++標準10進法 | 10進法 | 8進法 | 16進法 | 大文字で16進法 | |
---|---|---|---|---|---|
signed | %lld | %lli | %llo | %llx | %llX |
unsgined | %llo | %llu | %llx | %llX |
最大値マクロ
_UI64_MAX
確認コード
#include <iostream> #include <limits> using namespace std; void main(){ cout<<"int"<<numeric_limits<int>::max()<<endl; cout<<"unsigned int"<<numeric_limits<unsigned int>::max()<<endl; cout<<"unsigned long "<<numeric_limits<unsigned long>::max()<<endl; cout<<"unsigned long long"<<numeric_limits<__int64>::max()<<endl; cout<<"double"<<numeric_limits<double>::max()<<endl; puts("サイズ"); printf("unsigned int=%d,unsigned long=%d size=%d\n",sizeof(unsigned int),sizeof(unsigned long),sizeof(unsigned long long)); }
もし16桁以上の数を無理やりキャストしようとしたら???
数としては大きさの体裁を保つけど、下の桁の方が0で埋まって大事な情報が失われちゃうのだ。
たとえば次のコードを実行してみよ。
public class Main { public static void main(String[] args) { double large_num=Long.MAX_VALUE; System.out.println(""+Long.MAX_VALUE+" 桁数:"+Long.toString(Long.MAX_VALUE).length()); System.out.printf("doubleにキャスト後:%f",large_num); } }
すると、、、
9223372036854775807 桁数:19 9223372036854776000.000000
あれー???5807の部分が6000になってるじゃあありませんか!!
そう、こうやって誤魔化されちゃうのです。