【问题标题】:lossless conversion of float to string and back: is it possible?将浮点数无损转换为字符串并返回:有可能吗?
【发布时间】:2012-02-17 21:55:23
【问题描述】:

这个问题是指 C/x86 上使用的 IEEE 标准浮点数。

是否可以将任何数字(即不包括 NaN 等特殊值)浮点数或双精度数表示为十进制字符串,以便将该字符串转换回浮点数/双精度数将始终准确地产生原始数字?

如果不是,什么算法告诉我给定的数字是否会发生转换错误?

如果是这样,请考虑:某些小数在转换为二进制时,在数值上与原始十进制值不同,但反之则不正确(因为二进制具有有限精度,因此任何十进制扩展都是有限的,并且如果不被截断就完美了),所以这是另一个问题......

是否有必要在十进制表示中引入故意错误以欺骗atof(或其他)函数以产生确切的原始数字,或者一个天真的、非截断toString函数是否足够(假设通常可以进行精确转换)?

【问题讨论】:

  • 什么语言/环境?从您提到的符号来看,它可能是 JavaScript,也可能是 C,或者完全是其他东西。 (本地的toString 几乎肯定对于真正的无损往返来说是足够的。)

标签: string floating-point floating-accuracy


【解决方案1】:

根据this page

实际上,IEEE754-1985 标准说 17 位十进制数字是 在所有情况下都足够了。不过好像有点标准 关于符合的实现是否必须保证无损的模糊 使用 17 位时的转换。

因此,将double 存储为至少有 17 位数字(正确舍入)的十进制字符串将保证它可以转换回二进制 double 而不会丢失任何数据。

换句话说,如果每个可能的双精度值都被转换为 17 位的十进制字符串(正确舍入),它们都将映射到不同的值。因此没有数据丢失。


我不确定单精度的最小截止值。但我怀疑它会是 8 位或 9 位数字。

【讨论】:

  • 浮点数为 9 位(参见 cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF 的第 4 页;另请参见 Goldberg 的论文,“二进制到十进制转换”部分。)
  • 您提到“正确舍入”。这不是漏洞吗?哪些实现通常不会或不能遵守?另外,实际的实现是否符合这个理论保证?
【解决方案2】:

鉴于 IEEE 格式只能表示有限数量的(二进制)数字,因此具有最低准确度(参见 epsilon),您只需要有限数量的(十进制)数字。当然,如果实现(strtodsnprintf)在 {all floats} 和 {one decimal representation for each float} 的集合之间具有恒等映射行为,则更好。

【讨论】:

    【解决方案3】:

    在 java 中,可以通过构造一个中间 BigDecimal 对象来将 double 从/转换为字符串:

    double doubleValue = ...;
    
    // From double to string
    String valueOfDoubleAsString = new BigDecimal(doubleValue).toString();
    // And back
    double doubleValueFromString = new BigDecimal(valueOfDoubleAsString).doubleValue();
    
    // doubleValue == doubleValueFromString
    

    此方法没有语言环境问题。 但是,特殊的双精度值(Infinite、NaN)当然不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-14
      • 2014-12-24
      • 1970-01-01
      • 2011-11-25
      • 2019-04-27
      • 1970-01-01
      • 1970-01-01
      • 2021-06-15
      相关资源
      最近更新 更多