2014-01-28 123 views
1

有一些特殊的格式(base-128)設計用於傳輸protobufselsewhere中使用的整數。當大多數整數很小時(它們需要一個字節用於最小的數字並且可能浪費一個字節用於其他字節),它們是有利的。浮點數的緊湊格式

我想知道在假定大多數實際上是小整數的情況下,浮點數是否有相似之處?


要由Alice解決了答案:我在想是這樣

void putCompressedDouble(double x) { 
    int n = (int) x; 
    boolean fits = (n == x); 
    putBoolean(fits); 
    if (fits) { 
     putCompressedInt(n); 
    } else { 
     putUncompressedLong(Double.doubleToLongBits(x)); 
    } 
} 

這個工程(除負零,我真的不關心),但它的浪費在fits == true的情況下。

回答

1

這取決於你的號碼分佈。幅度並不重要,因爲它通過浮點的指數字段表示。它的尾數通常是儲存方面貢獻最大的「重量」。

如果你的花車主要是整數,則可以通過轉換爲int(通過Float.floatToIntBits()),並檢查了多少尾隨零有(小型INT值應該有高達23尾隨收穫零)。當使用一個簡單的方案來編碼小INT的,你可以實現編碼彩車簡稱爲:

int raw = Float.floatToIntBits(f); 
raw = Integer.reverse(raw); 
encodeAsInt(raw); 

(解碼簡直是在倒車過程中)。 這樣做只是將尾數的尾隨零移動到int表示的最高位,這對於爲小整數設計的編碼方案是友好的。

同樣可以適用雙倍< - >長。

+0

我接受你的解決方案,因爲它很好,很簡單。在我自己的答案中,我給出了結果(可以實現更好的壓縮,但它要複雜得多)。 – maaartinus

0

可能不是,這幾乎肯定不是你想要的。

如注意到的at this stack overflow post,浮點數不以平臺無關的方式存儲在協議緩衝區中;他們基本上是位表示,然後使用聯合進行投射。這意味着浮點數將佔用4個字節和雙8個字節。 這幾乎可以肯定你想要

爲什麼?浮點數不是整數。整數是一個結構良好的羣體;每個數字都是有效的,每個比特模式代表一個數字,並且它們完全代表它們的整數。例如浮點不能精確地表示許多重要的數字:大多數浮點數不能精確地表示0.1。無窮問題,NAN的等等,都使得壓縮格式成爲一項不重要的任務。

如果你有一個浮點小整數,然後將它們轉換成小整數或一些定點精度格式。例如,如果你知道你只有... 4 sigfigs,你可以從浮點轉換爲一個固定點,節省2個字節。只要確保每一端都知道如何處理這種類型,你就會變得金黃。

但谷歌在這種情況下可能會嘗試並節省空間的任何操作都將重新發明輪子並具有潛在危險。這可能就是爲什麼他們儘量不去弄亂花車。

+0

我不能保證我的double是整數。我知道他們中的大多數都是,他們適合兩​​個字節,但也需要處理一般情況。我更新了mu問題。 – maaartinus

0

我非常喜歡杜蘭達的解決方案。儘管其簡單性,它表現相當不錯,至少對於float s。對於指數超過一個字節的double s,可能會有一些額外的位重新排列。下表給出了最多爲D數字的數字的編碼長度,也考慮了負數。在每列中,第一個數字給出了所需的最大字節數,而括號中的數字是平均值。

D AS_INT REV_FLOAT REV_DOUBLE BEST 
1: 1 (1.0) 2 (1.8) 3 (2.2) 1 (1.0) 
2: 2 (1.4) 3 (2.4) 3 (2.8) 2 (1.7) 
3: 2 (1.9) 3 (2.9) 4 (3.2) 2 (2.0) 
4: 3 (2.2) 4 (3.3) 4 (3.8) 3 (2.6) 
5: 3 (2.9) 4 (3.9) 5 (4.1) 3 (3.0) 
6: 3 (3.0) 5 (4.2) 5 (4.8) 4 (3.5) 
7: 4 (3.9) 5 (4.8) 6 (5.1) 4 (3.9) 
8: 4 (4.0) 5 (4.9) 6 (5.8) 5 (4.3) 
9: 5 (4.9) 5 (4.9) 6 (6.0) 5 (4.9) 

四種不同的方法進行了測試:

  • AS_INT:只需將數字轉換爲int。這是無法使用的,但給我們一個下限。
  • REV_FLOAT:Durandal的方法適用於float s。
  • REV_DOUBLE:Durandal的方法適用於double s。
  • BEST:對問題描述的我自己的方法的改進。相當複雜。