簡體   English   中英

浮點數的緊湊格式

[英]Compact format for floating-point numbers

有一些特殊格式(base-128)設計用於傳輸protobufs其他地方使用的整數。 當大多數整數較小時(它們需要最小大小的單個字節,而其他整數可能浪費一個字節),它們是有利的。

我想知道在大多數浮點數實際上都是小整數的情況下,是否存在類似的浮點數?


為了解決愛麗絲的答案:我在考慮類似

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情況下fits == true浪費。

這取決於您的號碼分布。 幅度並不重要,因為它通過浮點數的指數字段表示。 通常,尾數在存儲方面貢獻最大的“重量”。

如果您的浮點數主要是整數,則可以通過轉換為int(通過Float.floatToIntBits())並檢查有多少尾隨零來獲得一些收益(對於較小的int值,最多應有23個尾隨零)。 當使用簡單的方案對小整數進行編碼時,您可以將浮動編碼簡單地實現為:

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

(解碼只是逆向過程)。 這樣做只是將尾數中的尾隨零移動到int表示形式的最高有效位,這對為小整數設計的編碼方案很友好。

同樣可以應用於double--long。

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

該堆棧溢出文章所述 ,浮點數未以與平台無關的方式存儲在協議緩沖區中。 它們本質上是逐位表示的,然后使用聯合進行轉換。 這意味着float將占用4個字節,再加上8個字節。 這幾乎可以肯定是您想要的

為什么? 浮點數不是整數 整數是一個結構良好的組; 每個數字都是有效的,每個位模式表示一個數字,並且它們恰好表示它們是整數。 浮點數不能精確表示許多重要數字:例如,大多數浮點數不能精確表示0.1。 無限性,NAN等的問題都使壓縮格式成為一項艱巨的任務。

如果浮點數中有小整數, 則將它們轉換為小整數或某些定點精度格式 例如,如果您知道只有.... 4個sigfig,則可以將浮點數轉換為短定點數,從而節省了2個字節。 只要確保每一端都知道如何處理這種類型,就可以了。

但是在這種情況下,谷歌可以做的任何嘗試來節省空間的操作都將重新發明輪子,並且有潛在的危險。 這可能就是為什么他們盡量不弄亂浮標的原因。

我非常喜歡Durandal的解決方案。 盡管它很簡單,但至少對於float ,它的表現還不錯。 對於double大於1個字節的指數,可能需要一些其他的位重排。 下表給出了最多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
  • REV_DOUBLE:Durandal的方法應用於double
  • 最好:問題中描述的我自己方法的改進。 相當復雜。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM