9

I can store a number as a Long and Double in HBase. Both of them takes 8 bytes in Java.

Advantage of Using Double is that it gives a more wider range for storing Whole Numbers.

However, i think range of Long is also enough for my use.

Does anyone has any idea about the serialization and de-serialization performance of Long vs Dobule? I am interested in comparison between them.

Thanks.

4

3 に答える 3

25

整数を格納する場合は、 を使用します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

ご了承ください

  1. Long.MAX_VALUE-100 の double 表現は、元の値と等しくありませ
  2. Long.MAX_VALUE-100 の double 表現に 1 を追加しても効果はありません
  3. この大きさでは、1 つの double 値と次に可能な double 値の差は 2000 です。

別の言い方をすれば、 のlong精度は 19 桁弱ですが、精度doubleは 16 桁しかありません。Double は 16 桁を超える数値を格納できますが、下位桁の切り捨て/丸めを犠牲にします。

19 桁を超える精度が必要な場合はBigInteger、パフォーマンスの低下が予想される に頼る必要があります。

于 2012-10-02T22:08:10.967 に答える
3

これは間違った戦いのように見えます:

Javaチュートリアルから

long データ型は、64 ビットの符号付き 2 の補数整数です。最小値は -9,223,372,036,854,775,808 で、最大値は 9,223,372,036,854,775,807 (包括的) です。

これは有効数字が 19 桁にかなり近い値です。

ウィキペディアより

これにより、15 桁から 17 桁の有効桁数の精度が得られます。

したがって、その明らかな「優位性」にもかかわらず、Double は Long よりも悪い結果をもたらします。ここで推測しているだけですが、直感的には、浮動小数点型のシリアル化/逆シリアル化は、整数データ型の同じ操作よりもコストがかかる操作だと思いますが、違いがあっても、最新のシステムでは非常に小さいでしょう。

したがって、整数を扱うときは、Long に固執してください。

于 2012-10-02T22:13:20.387 に答える
2

long具体的に知らなくても、aと a の両方doubleが同じシリアライゼーションを持っていると想像できます。つまり、64 ビットを取得してネットワークに接続します。同様に、デシリアライゼーションは、ネットワークから 64 ビットを取り出し、それらがlongorを表していると宣言するだけの問題だと思いdoubleます。任意の 64 ビットは有効なlongorを表すためdouble(ただし、すべてが有限の double を表すわけではありません)、検証や追加の作業はありません。

于 2012-10-02T22:24:58.527 に答える