我正在编写序列化/反序列化大型数据结构的函数,以便以后进行高效的重新加载。有一组特殊的十进制数,精度不是很大,我想将它们存储在4字节的二进制数据中。
对于大多数人来说,将字节读入缓冲区并使用memcpy将它们放入浮点数就足够了,这是我发现的最常见的解决方案。但是,这不是可移植的,因为该软件所用系统上的浮动不保证大小为4个字节。
我想要的是非常便携的东西(这是我仅限于C89的原因之一)。我并不喜欢4字节存储,但对我来说这是一个很有吸引力的选择。我完全反对将数字存储为字符串。我熟悉字节序问题,这些事情已经被考虑在内了。
因此,我所寻找的是一种独立于系统的方法,用于在少量二进制数据(最好是大约4个字节)中存储和检索浮点数。我愚蠢地想象这将是这项任务中最容易的部分,因为它似乎是一个常见的问题,但是热门的搜索引擎和各种参考书都没有提供任何物质帮助。
答案 0 :(得分:2)
你可以将它们存储在32位IEEE浮点格式中(或者非常接近它,例如你可能会限制denorms和NaN)。然后让每个平台根据需要进行调整,以将其自己的float
类型强制转换为该格式并返回。
当然会有一些准确性的损失,但如果你将不同精度的浮点值从一个系统转移到另一个系统,那么这是不可避免的。
应该可以编写可移植代码以找到与原始float
值最接近的IEEE值,反之亦然,如果需要的话。但是,你真的不想使用它,因为它可能远远低于利用知道float
格式的代码的效率。在平台使用IEEE表示的常见情况下,它是无操作或简单的缩小/扩展转换。即使在最糟糕的情况下,你可能会遇到,只要它是二进制分数,你基本上只需要提取符号,指数和有效位,并用它们做正确的事情(如果它太大,则丢弃有效数字的位,调整指数的偏差和可能的宽度,用下溢和溢出做正确的事情。
如果您想避免在保存文件然后在同一系统上重新加载(但该系统不使用32位IEEE)的情况下丢失准确性,您可以查看在文件中存储指示格式的一些数据(每个值的大小,有效数和指数的位数),然后以原始精度存储每个值,以便只有在它被加载到不太精确的系统时才会被舍入。我不知道ASN.1是否有一个标准来沿着这些线编码浮点值,但它是我期望的那种复杂的技巧。
答案 1 :(得分:0)
检查出来:http://steve.hollasch.net/cgindex/coding/portfloat.html
它们提供了一个可移植的例程,并没有增加太多的开销。