c - C (C89) 中十进制数的有效磁盘存储

标签 c serialization floating-point storage disk

我正在编写序列化/反序列化大型数据结构的函数,以便稍后高效地重新加载。有一组特定的十进制数,其精度不是什么大问题,我想将它们存储在 4 个字节的二进制数据中。

对于大多数人来说,将字节读入缓冲区并使用 memcpy 将它们放入 float 就足够了,这是我找到的最常见的解决方案。但是,这不是可移植的,因为不能保证此软件适用的系统上的 float 大小为 4 个字节。

我想要的是非常便携的东西(这是我仅限于 C89 的原因之一)。我不拘泥于 4 字节存储,但它对我来说是一个有吸引力的选择。我完全反对将数字存储为字符串。我熟悉字节顺序问题,并且已经考虑到了这些问题。

因此,我正在寻找一种独立于系统的方法来存储和检索少量二进制数据(最好是 4 字节左右)中的 float 。我愚蠢地以为这是这项任务中最简单的部分,因为这似乎是一个普遍的问题,但流行的搜索引擎和各种引用书都没有提供任何实质性帮助。

最佳答案

您可以将它们存储为 32 位 IEEE 浮点格式(或非常接近它的格式,例如,您可能会限制 denorms 和 NaN)。然后让每个平台根据需要进行调整,将其自己的 float 类型强制转换为该格式并返回。

当然会有一些精度损失,但如果您将不同精度的浮点值从一个系统传输到另一个系统,那无论如何这是不可避免的。

应该可以编写可移植代码来找到最接近 native float 值的 IEEE 值,反之亦然,如果需要的话。不过,您不会真的想使用它,因为它的效率可能远低于利用了解 float 格式的代码。在平台使用 IEEE 表示的常见情况下,它是无操作或简单的缩小/扩大转换。即使在您可能遇到的最坏情况下,只要它是二进制小数,您基本上只需要提取符号、指数和有效位,并对它们做正确的事情(如果有效位太大,则丢弃有效位,调整偏差和可能的指数宽度,对下溢和上溢做正确的事情)。

如果你想避免在保存文件然后重新加载到同一系统(但该系统不使用 32 位 IEEE)的情况下失去准确性,你可以考虑存储一些指示文件格式的数据(每个值的大小,有效位数和指数的位数),然后以 native 精度存储每个值,以便它只有在加载到精度较低的系统时才会被四舍五入。我不知道 ASN.1 是否有一个标准来沿着这些线对浮点值进行编码,但这是我期望从中得到的那种复杂的技巧。

关于c - C (C89) 中十进制数的有效磁盘存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7612080/

相关文章:

C 在数组中添加和搜索已解析的数据

java - 无法使用 Jackson XmlMapper 反序列化包装列表

java - Java如何将 float 转换为字符串

c - NetBeans (7.3.1) 检测到 C 中的虚假错误

c - 直接函数调用是否比回调函数调用执行得更快?

java - Wicket - 持久化和非持久化 JPA 实体的序列化

java - 不安全或未经检查的操作警告

c++ - 整数在 float 中的精确表示

floating-point - 大多数语言无法正确舍入 31.45

将 SSL 私钥转换为字符串