【问题标题】:Is there a solution for Floating point Arithmetic problems in C++?C++ 中的浮点算术问题有解决方案吗?
【发布时间】:2010-10-28 14:44:43
【问题描述】:

我正在做一些浮点运算并且有精度问题。对于相同的输入,两台机器上的结果值不同。我阅读了@@Why can't I multiply a float? 的帖子并阅读了网络上的其他材料,并了解到它与浮点的二进制表示和机器 epsilon 上的有关。但是,我想检查是否有办法解决这个问题/C++ 中浮点运算的一些解决方法?我正在将浮点数转换为无符号的存储短,并在必要时转换回来。但是,当我将其转换回 unsigned short 时,精度(到小数点后 6 位)在一台机器上保持正确,但在另一台机器上失败。

//convert FLOAT to short

unsigned short sConst = 0xFFFF;

unsigned short shortValue = (unsigned short)(floatValue * sConst);

//Convert SHORT to FLOAT

float floatValue = ((float)shortValue / sConst);

【问题讨论】:

  • 到底是什么问题?在两台不同的机器上乘法结果略有不同这一事实本身并不是问题。为什么它适合你?
  • 由于没有说明实际问题,因此无法正确回答此问题。投票结束不是一个真正的问题。
  • 另一台机器的精度是多少? 1 位小数? 5?
  • 提供来自两台机器的示例结果,用于相同的输入和每种情况下使用的处理器的详细信息,以及编译器和编译器选项(如果它们不同)。

标签: c++ floating-point precision multiplication epsilon


【解决方案1】:

short 必须至少为 16 位,并且在很多实现中,它就是这样。 unsigned 16 位 short 将保存从 0 到 65535 的值。这意味着 short 将不能保存完整的五位精度,当然也不是六位。如果要六位数,则需要 20 位。

因此,任何精度损失都可能是由于您试图将六位数的精度压缩成小于五位数的结果。除了使用可能占用与float 一样多的存储空间的整数类型之外,没有其他解决方案。

我不知道为什么它似乎可以在一个给定的系统上工作。您在两者上使用相同的数字吗?是否有一个使用了较旧的浮点系统,并且一个巧合地在您尝试的样本上给出了您所期望的结果?是否可能使用比另一个更大的short

【讨论】:

    【解决方案2】:

    如果您想使用本机浮点类型,最好的办法是断言您的程序输出的值与一组参考值没有太大差异。

    “太多”的准确定义完全取决于您的应用程序。例如,如果您在不同平台上计算a + b,您应该会发现这两个结果在彼此的机器精度范围内。另一方面,如果你正在做一些更复杂的事情,比如矩阵求逆,结果的差异很可能会超过机器精度。准确地确定您期望结果彼此之间的接近程度是一个非常微妙和复杂的过程。除非您确切知道自己在做什么,否则确定应用程序下游所需的精度并验证结果是否足够精确可能会更安全(也更明智)。

    要了解如何稳健地计算两个浮点值之间的相对误差,请参阅此答案和其中链接的浮点指南:

    Floating point comparison functions for C#

    【讨论】:

      【解决方案3】:

      【讨论】:

      • 问题中没有证据表明浮点数具有终止的十进制表示。
      【解决方案4】:

      不要使用 0xFFFF,而是使用它的一半,即 32768 进行转换。 32768 (Ox8000) 具有 1000000000000000 的二进制表示,而 OxFFFF 具有 1111111111111111 的二进制表示。 Ox8000 的二进制表示清楚地表明,转换期间的乘法和除法运算(在转换回浮点数时转换为短(或))不会改变精度值零后。然而,对于一侧转换,OxFFFF 更可取,因为它会导致更准确的结果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-14
        • 2021-09-06
        • 2020-12-15
        • 2011-07-04
        • 1970-01-01
        • 2023-03-31
        • 2012-01-25
        相关资源
        最近更新 更多