在我的应用程序中,我将使用浮点值来存储地理坐标(纬度和经度)。
我知道这些值的整数部分分别在[-90, 90]
和[-180, 180]
范围内。此外,我还要求对这些值强制执行一些固定的精度(现在它是0.00001
但可以在以后更改)。
在研究单精度浮点类型(float
)之后,我可以看到包含我的值只是有点小。那是因为180 * 10^5
大于2^24
(浮点数有效数的大小)但小于2^25
。
所以我必须使用double。但问题是我要存储大量的这些值,所以我不想浪费字节,存储不必要的精度。
那么在将我的double值(具有固定的整数部分范围和指定的精度X)转换为java中的字节数组时,如何执行某种压缩?因此,例如,如果我使用我的示例中的精度(0.00001
),我最终会为每个值使用5个字节。
我正在寻找一种轻量级的算法或解决方案,因此它并不意味着大量的计算。
答案 0 :(得分:6)
要将数字x
存储到(例如)0.00001
的固定精度,只需存储最接近100000 * x
的整数。 (顺便说一句,这需要26位,而不是25位,因为你也需要存储负数。)
答案 1 :(得分:3)
正如TonyK中his answer所述,使用int
来存储数字。
要进一步压缩数字,请使用局部性:地理坐标通常是“聚集”(比如城市街区的轮廓)。使用固定参考点(完整的2x26位分辨率),然后将偏移量存储到最后一个坐标为byte
s(给出+/- 0.00127)。或者,使用short
,它可以为您提供超过一半的值范围。
请确保在仅提供double
作为外部API的类中隐藏压缩/解压缩,以便您可以随时调整精度和压缩算法。
答案 2 :(得分:2)
考虑到您的使用案例,我仍会使用 double 并直接压缩它们。
原因是强大的压缩器,如7zip,非常善于处理“结构化”数据,这是一个双数组(一个数据= 8个字节,这是非常规则和可预测的)。
你可能“手工”出现的任何其他优化可能都会低劣或提供微不足道的优势,同时会花费你的时间和风险。
请注意,您仍然可以应用在压缩之前将double转换为int的“技巧”,但我真的不确定它是否会带给您实实在在的好处,而另一方面它会严重降低您应对的能力未来不可预见的数字范围。
[编辑]根据源数据,如果“低于精度级别”位是“噪声”,则可以通过舍入值或压缩比来消除噪声位。甚至直接在最低位上应用掩码(我猜这最后一种方法不会让纯粹主义者满意,但至少你可以用这种方式直接选择你的精度等级,同时保持可用的全部可能值)。
因此,总结一下,我建议你的双数组direct LZMA compression。