2012-10-02 82 views
4

我可以在HBase中將數字存儲爲Long和Double。它們都是Java中的8個字節。在java中雙倍長序列化

使用Double的優勢在於它提供了更寬的範圍來存儲整數。

不過,我認爲Long的範圍對我來說也是足夠的。

有沒有人對Long vs Dobule的序列化和反序列化性能有所瞭解?我對他們之間的比較感興趣。

謝謝。

+0

'long'和'double'或'Long'和'Double'以及你在說什麼樣的序列化? –

回答

14

如果要存儲整數,請使用Long。您的陳述「使用Double的優點是它提供了一個更寬的範圍來存儲整數」是不正確的。兩者都是64位長,但double必須使用指數的一些位,留下較少的位來表示幅度。您可以在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的雙表示法確實NOT等於初始值
  2. 添加1〜Long.MAX_VALUE-100的雙表示沒有效果
  3. 以該大小,一個雙鍵和下一個可能的雙值之間的差爲2000。

說這是的另一種方法long的精度剛好低於19位,而double的精度只有16位。 Double可以存儲大於16位數字的數字,但是會以低位數字截斷/舍入爲代價。

如果您需要19位以上的數字精度,您必須求助於BigInteger,預計性能下降。

+6

+1 - 性能無關緊要;這兩種類型有完全不同的目的。 – duskwuff

+0

是的,我打算存儲整數(整數)。你能告訴我,如果我在Double中存儲整數,我將如何失去精度?雙 最大值爲:17976931348623157000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0 長的最大值爲:9223372036854775807 –

+0

我無法理解「比某些上限可以不再存儲毗鄰的較大的數字‘整數’......鑑於以上的整數值這個門檻,「下一個」可能的雙倍將比前一個數字大1以上。「你能詳細解釋一下嗎? Long的問題在於它只能有19位數字,將來我可能會有超過19位數字的數字。 –

2

這看起來像錯誤的戰鬥:

Java Tutorial

長數據類型是64位有符號二進制補碼整數。它有 最小值-9,223,372,036,854,775,808和最大值 9,223,372,036,854,775,807(含)。

這是非常接近19個顯著數字

Wikipedia

這給從15 - 17顯著十進制數字精度。

因此,儘管它明顯的「優越性」,雙將爲您服務比龍更糟糕。我只是在這裏猜測,但直覺上我會說浮點類型的序列化/反序列化是比完整數據類型的操作更昂貴的操作,但即使存在差異,它們在現代系統上也會很小。

所以,在使用整數時,請堅持Long。

+0

龍的問題是,我可能有超過19個有效數字的整數。 –

0

不知道具體,我會想象一個longdouble具有相同的序列化:採取64位,並把它們放在電線上。同樣,我可以想象,反序列化只是將64位數據從電線上取下來並聲明它們現在代表longdouble。任何64位將代表有效的longdouble(儘管不是所有的都會代表有限雙倍),所以沒有任何驗證或額外的工作。