【问题标题】:C/C++ floating point issue [duplicate]C / C ++浮点问题[重复]
【发布时间】:2013-05-11 10:30:31
【问题描述】:

我正在努力解决一个基本的浮点精度问题。问题来了:

double d = 0.1;
d += 0.1;
d += 0.1;

d == 0.3 ? std::cout << "yes" : std::cout << "no";

运行代码,你会得到“否”

我了解 C/C++ 以二进制形式存储值,并且二进制存储无法准确存储每个值。我也明白这些小错误会随着您对它们进行各种数学运算而复杂化(即 d += 0.1;)。

我的问题是我是否需要测试 d == 0.3(以合理的精度......正如上面代码的明确意图)......我该怎么做?我希望答案不是:

if (d > 0.2999 && d < 0.3001) ...

也..这行得通

float f = 0.1;
f += 0.1;
f += 0.1;

f == 0.3f ? std::cout << "yes" : std::cout << "no";

但我在该语言中找不到等效的“0.3d”。

谢谢

【问题讨论】:

标签: c++ c floating-point


【解决方案1】:

0.3ffloat 文字。如果你想要一个double 文字,你必须使用0.3(不带后缀),因为double 是默认值。 0.3l 将是 long double

【讨论】:

  • 我们看到的是同一个问题吗? (也许它已被编辑。)0.3f 用于第二个 sn-p,其中 f 是 float。问题中没有0.3l
  • @delnan:我回答了这部分问题(看看std::abs() / fabs() 已经被其他人覆盖了):"...但我找不到等效的 "0.3 d"在语言中。"
  • 我误读了关于0.3l 的部分(0.3 是双重含义的解释),因此误读了您回答的意图。没关系。
【解决方案2】:

您可能需要用一个很小的数字比较d0.3f 之间的差异。

你可以试试:

 float epsilon = 1e-5;
 if (fabs(d - 0.3f) < epsilon)
 {
     std::cout << "yes" ;
 }
 else{
     std::cout << "no " ;
 }

【讨论】:

    【解决方案3】:

    将相等性测试到某个“容差水平”的一种常见方法是使用fabs

    if (fabs(d - 0.3) < 1E-8) {
         ...
    }
    

    【讨论】:

    • 从略读 cppreference.com 看来,std::absfloatdouble 重载,我无法想象不应该出现的原因。只有 C abs 是特定于整数的。那么为什么要使用fabs
    • @delnan 因为问题被标记为 C 和 C++ :)
    • 没注意到,谢谢。但由于 OP 在问题中使用 C++ 代码,我假设 C 标记意义不大。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-20
    • 2012-10-27
    • 2021-09-16
    • 2011-02-23
    • 2011-10-15
    相关资源
    最近更新 更多