压缩具有指定范围和精度的浮点数

时间:2011-12-05 08:25:50

标签: java compression floating-point

在我的应用程序中,我将使用浮点值来存储地理坐标(纬度和经度)。

我知道这些值的整数部分分别在[-90, 90][-180, 180]范围内。此外,我还要求对这些值强制执行一些固定的精度(现在它是0.00001但可以在以后更改)。

在研究单精度浮点类型(float)之后,我可以看到包含我的值只是有点小。那是因为180 * 10^5大于2^24(浮点数有效数的大小)但小于2^25

所以我必须使用double。但问题是我要存储大量的这些值,所以我不想浪费字节,存储不必要的精度。

那么在将我的double值(具有固定的整数部分范围和指定的精度X)转换为java中的字节数组时,如何执行某种压缩?因此,例如,如果我使用我的示例中的精度(0.00001),我最终会为每个值使用5个字节。 我正在寻找一种轻量级的算法或解决方案,因此它并不意味着大量的计算。

3 个答案:

答案 0 :(得分:6)

要将数字x存储到(例如)0.00001的固定精度,只需存储最接近100000 * x的整数。 (顺便说一句,这需要26位,而不是25位,因为你也需要存储负数。)

答案 1 :(得分:3)

正如TonyKhis answer所述,使用int来存储数字。

要进一步压缩数字,请使用局部性:地理坐标通常是“聚集”(比如城市街区的轮廓)。使用固定参考点(完整的2x26位分辨率),然后将偏移量存储到最后一个坐标为byte s(给出+/- 0.00127)。或者,使用short,它可以为您提供超过一半的值范围。

请确保在仅提供double作为外部API的类中隐藏压缩/解压缩,以便您可以随时调整精度和压缩算法。

答案 2 :(得分:2)

考虑到您的使用案例,我仍会使用 double 并直接压缩它们。

原因是强大的压缩器,如7zip,非常善于处理“结构化”数据,这是一个双数组(一个数据= 8个字节,这是非常规则和可预测的)。

你可能“手工”出现的任何其他优化可能都会低劣或提供微不足道的优势,同时会花费你的时间和风险。

请注意,您仍然可以应用在压缩之前将double转换为int的“技巧”,但我真的不确定它是否会带给您实实在在的好处,而另一方面它会严重降低您应对的能力未来不可预见的数字范围。

[编辑]根据源数据,如果“低于精度级别”位是“噪声”,则可以通过舍入值或压缩比来消除噪声位。甚至直接在最低位上应用掩码(我猜这最后一种方法不会让纯粹主义者满意,但至少你可以用这种方式直接选择你的精度等级,同时保持可用的全部可能值)。

因此,总结一下,我建议你的双数组direct LZMA compression