整数を格納する場合は、 を使用しますLong
。「Doubleを使用する利点は、整数を格納するためのより広い範囲を提供することです」というあなたの声明は正しくありません。どちらも 64 ビット長ですがdouble
、指数にいくつかのビットを使用する必要があり、大きさを表すビットが少なくなります。より大きな数値を a に格納できdouble
ますが、精度が失われます。
言い換えれば、ある上限よりも大きい数値の場合、隣接する「整数」を格納できなくなります...このしきい値を超える整数値を指定すると、可能な「次」double
は前の数値よりも 1 以上大きくなります。
例えば
public class Test1
{
public static void main(String[] args) throws Exception
{
long long1 = Long.MAX_VALUE - 100L;
double dbl1 = long1;
long long2 = long1+1;
double dbl2 = dbl1+1;
double dbl3 = dbl2+Math.ulp(dbl2);
System.out.printf("%d %d\n%f %f %f", long1, long2, dbl1, dbl2, dbl3);
}
}
これは以下を出力します:
9223372036854775707 9223372036854775708
9223372036854776000.000000 9223372036854776000.000000 9223372036854778000.000000
ご了承ください
- Long.MAX_VALUE-100 の double 表現は、元の値と等しくありません
- Long.MAX_VALUE-100 の double 表現に 1 を追加しても効果はありません
- この大きさでは、1 つの double 値と次に可能な double 値の差は 2000 です。
別の言い方をすれば、 のlong
精度は 19 桁弱ですが、精度double
は 16 桁しかありません。Double は 16 桁を超える数値を格納できますが、下位桁の切り捨て/丸めを犠牲にします。
19 桁を超える精度が必要な場合はBigInteger
、パフォーマンスの低下が予想される に頼る必要があります。