我想将一些弧度角写入二进制文件。有什么办法可以节省空间吗?
我考虑将它们转换为度数并将它们写成一个短,但是当转换为一个短时,它们会丢失他们的小数部分,所以这不会起作用......
有任何想法吗?
编辑:我只需要 2 或 3 个小数点精度
您需要多少精度/分辨率?
如果您可以使用半个圆的精度/分辨率,则每个值 1 位就足够了:也就是说,您可以在一个字节中容纳 8 个值。
...
你有两件事要担心:范围和精度。而且您还没有向我们提供有关其中任何一个的足够信息。
所以我会做出一些合理的(我希望的)假设。
我假设所有值都在 0 到 2π(0 到 360°)的范围内。
如果您存储诸如 32-bit 之类的值float
,您将使用 1 位作为符号(对于始终为非负数的数字),8 位作为指数(永远不会很大),以及 23 位作为有效数(这可能比您需要的更精确)。如果您使用 64-bit double
,您显然会使用更多空间。
最明显的解决方案是使用一个小的无符号类型(因为您不需要负值),使用定点表示,以便值1
表示弧度的一部分。对于从 0 到 2π(0 到大约 6.28)的值,十进制二进制点前需要 3 位。现在你只需要决定你想要多少位的分数。
如果您使用 8 位无符号类型(通常为unsigned char
),则在二进制点之后为您提供 5 位,因此值 1 表示 2 -5弧度,大约为 1.82°。这几乎不足以为您提供您说需要的“2 或 3 位小数精度”,但我怀疑它比您实际想要的更粗糙。
如果您使用 16 位无符号类型(通常为unsigned short
),则在二进制点之后为您提供 13 位,因此值 1 表示 2 -13弧度;这大约是 0.007°,或大约 25 角秒。这对于您的目的来说可能已经足够精确了,它通常是float
.
所有这些都假设仅将值存储为 32 位float
s 是不够的。如今,磁盘空间(如果您担心的话)很便宜,而且越来越便宜。
另请注意,如果您想在不同系统之间共享数据,则将二进制值存储在文件中可能会出现问题。特别是字节顺序可能是一个问题。如果您可以定义一种字节流格式(例如,表示 16 位无符号值的字节对,最重要的字节在前——这就是“网络字节顺序”),您就可以缓解这个问题。整数值比浮点值更容易处理。
压缩?
实现起来可能有点贵,但它可能比紧密打包的二进制数据占用更少的空间。另外,未压缩的形式几乎可以是任何东西,例如人类可读的 ASCII。
Quake 源代码中有一个方法可以将它们写成一个字节,如下所示:
((int)radian*256/360) & 255 //radian is the angle
然后像这样读入:
b * (360.0f/256) //b is the byte read in
我测试了它,它留下了大约 2 个小数位的精度,这对我来说应该没问题。