【问题标题】:How to write decimals in a well defined non-custom format如何以定义明确的非自定义格式编写小数
【发布时间】:2021-05-03 15:33:47
【问题描述】:

假设我有一个传感器返回测量数据(例如每秒 6 x 50 个值)。每个值都是单精度浮点数范围内的小数。我需要将这些数据写入一个文件,然后由另一个应用程序读取该文件以进行其他操作。格式化/编码文件的最有效方法是什么?

起初我认为 CSV 是为了简单起见,但使用科学记数法会导致每个小数的长度为 9 个字节或更多(例如 -4,97E-03)。在大量传感器上长时间保留数据的情况下,这可能是存储限制的问题,也因为这些数据具有高熵,因此压缩没有多大帮助。

所以我考虑将小数保存为浮点数(4 个字节)会节省大量数据,但我不知道哪些格式提供了定义明确的结构来存储浮点数表。是否有类似逗号分隔值的东西,其中值采用 IEEE754 格式,或类似的东西?我问这个是因为我想避免定义自定义格式。

【问题讨论】:

  • float的大多数C实现使用的格式实际上是IEEE-754定义的二进制交换格式,这意味着您可以直接将float的字节写入某些通信或存储介质并读取从中恢复值的字节,前提是字节按匹配顺序读取和写入(读取器和写入器都是大端或小端,或者他们根据需要安排重新排列字节)。如果您想使用人类可读或文本友好的格式,请考虑使用 %a 来表示十六进制浮点数。
  • 如果你用二进制存储,一个四字节元素的数组就足够了;不需要逗号之类的分隔符。无论使用何种整体格式,例如在开始时给出数组维度,都由您决定。
  • 更多地描述您的数据:范围、单位、精度。原始数据是整数吗?
  • @EricPostpischil 我编辑了问题,澄清我想避免定义自定义格式

标签: data-structures floating-point format


【解决方案1】:

正如您所说,以人类可读的文本格式(如 CSV)编码浮点数的空间效率非常低,因为每个 32 位浮点数需要十几个字符来编码。作为测试,我生成了 100 万个随机 32 位浮点数并将它们保存为文本文件:

-5.92667373e+04
-1.10473797e+05
7.58996562e+04
3.52729886e+04
...

此文件的大小为 15,499,059 字节。 但是,这样的文本文件压缩得非常好! 通过 gzip 运行文件后,文件大小减小到 5,925,628 字节。这还不错,大约是将浮点数存储为二进制数据(4,000,000 字节)所需的大小的 1.5 倍。

32 位浮点数表示大约 7 位有效数字的精度,但这对于表示测量值来说可能是多余的,尤其是在已知测量值不如这个精度的情况下。使用文本格式,您可以通过打印更少的有效数字来节省空间。或者,如果写入二进制数据,您可以通过向下舍入到 16-bit half-precision floats 或 16 位 fixed-point representation 将成本降低到一半。

正如 Eric 评论的那样,您可以直接编写原始二进制数据以及数组维度或您需要的任何其他数据,并提出您自己的临时格式。但如果您更愿意使用现有的标准格式,这里有一些建议:

  • NPY format 由 Python numpy 库原生支持,它可以表示浮点数组或任何其他可以放入 numpy 数组的内容。如果您已经在 Python 中工作,使用 np.loadnp.save 可以轻松读取和写入 NPY 文件。其他语言中也有 NPY 的实现,例如 C++ 中的 https://github.com/rogersce/cnpy 和 Rust 中的 https://docs.rs/npy/0.4.0/npy

  • FITS format 广泛用于天文学。 FITS 使用简单的二进制编码存储任意大小和维数的浮点数据数组,并且它可以在文本标题字段中存储任意元数据。格式很简单,因此实现您自己的阅读器和编写器相对简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    • 1970-01-01
    相关资源
    最近更新 更多