[英]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)
測試了四種不同的方法:
int
。 這是無法使用的,但給了我們一個下限。 float
。 double
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.