2014-01-28 97 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:对问题描述的我自己的方法的改进。相当复杂。