【问题标题】:How to determine the last nonzero decimal digit in a float?如何确定浮点数中最后一个非零十进制数字?
【发布时间】:2012-05-11 17:45:44
【问题描述】:

我正在编写一个浮点打印和格式化库,并希望避免打印尾随零位。

为此,我想准确确定小数点后前 N 个小数位内的最后一个非零数字。我想知道是否有一种特别有效的方法可以做到这一点。

【问题讨论】:

  • 我没有证据,但我的直觉是你只需要计算出第一个N 小数位,然后检查零。我猜测的原因是,如果您将(例如)1.00049 打印到小数点后 3 位,那么要知道有任何尾随零,您必须确定第 4 位不是5。如果不告诉你前面的数字,我认为没有任何捷径可以告诉你。我确信有很多小捷径可以有效地解决所有 4 个问题。

标签: c++ floating-point ieee-754


【解决方案1】:

这个(不平凡的)问题已经完全解决了。这个想法是打印出足够多的数字,这样如果将打印的数字转换回浮点数,就会得到与开始时完全相同的数字。

相关论文是 Robert Burger 和 R. Kent Dybvig 的“快速准确地打印浮点数”。可以here下载。

【讨论】:

    【解决方案2】:

    您必须将浮点数转换为字符串,然后修剪尾随零。

    我认为这不是很有效,但我觉得可能没有更简单的算法

    【讨论】:

      【解决方案3】:

      显而易见的解决方案是将所有数字放在char[N] 中,并在打印前检查最后一位数字。但我敢打赌,你自己也想过这一点。

      我能想到的唯一其他解决方案是2^(-n) 的小数部分有n 非零数字。

      因此,如果二进制表示中的最后一个非零是2^(-n),那么十进制扩展中将恰好有n 非零数字。因此,查看 binary 表示将告诉您有关 decimal 表示的一些信息。

      但是,这只是部分解决方案,因为舍入可能会引入额外的尾随零。

      【讨论】:

        【解决方案4】:
        std::cout.precision(n);
        

        //其中 n 是您希望在小数点后显示的数字。 如果在精度限制之前但在小数点之后存在零, 它会自动避免。

        eg. std::cout.precision(5);
        

        那么我的条件被评估为 5.55000 只会打印 5.55

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-12
          • 2023-01-24
          • 1970-01-01
          • 2018-01-06
          • 1970-01-01
          相关资源
          最近更新 更多