2

我正在学习一个开始的 C++ 类,而我的书(Starting Out with C++ Early Objects 7th edition)有一个非常糟糕的例子来说明如何检查浮点变量的值。

有问题的书籍示例(文件名 pr4-04.cpp):

// This program demonstrates how to safely test a floating-point number
// to see if it is, for all practical purposes, equal to some value.
#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    double result = .666667 * 6.0; 

    // 2/3 of 6 should be 4 and, if you print result, 4 is displayed.
    cout << "result = " << result << endl;

    // However, internally result is NOT precisely equal to 4.
    // So test to see if it is "close" to 4.
    if (abs(result - 4.0 < .0001))
        cout << "result DOES equal 4!" << endl;
    else
        cout << "result DOES NOT equal 4!" << endl;

return 0;
}

我在 Ubuntu 中使用 g++ 来编译我的代码,如下所示:

g++ pr4-04.cpp -o pr4-04 && ./pr4-04

我得到这个错误:

error: call of overloaded ‘abs(bool)’ is ambiguous

我可以通过将 abs() 更改为 fabs() 来解决这个问题,但这仍然非常令人困惑!为什么这本书给了我们无法编译的东西,或者这只是我?为什么“结果”的 cout 给出 4 而不是 4.000002?为什么这个值在 if{} 语句中使用时似乎会发生变化?

我知道我们不能只使用 == 来检查等价,但是为什么我需要使用绝对值呢?无论我是否使用它,我都会得到相同的答案。那么有什么意义呢?

更不用说,这似乎是检查浮点等价的一种非常糟糕的方法。有一个更好的方法吗?这个话题似乎非常重要

我在stackoverflow上找到了这个主题,但是他们的解决方案:

fabs(f1 - f2) < precision-requirement
fabs(f1 - f2) < max(fabs(f1), fabs(f2)) * percentage-precision-requirement

就我的 4 章 C++ 经验而言,这对我来说没有多大意义。我将不胜感激一些帮助。我们的书给了我多达 6 句话来解释这一切。

编辑:根据一些人的建议,我试图找到一个勘误页面,但是在搜索教科书、互联网和我的课程网站 30 分钟后,我只能找到这个需要登录的可下载 zip 文件-_-

我也完美地复制了代码。那不是的错字,我直接从带有代码的 CD 上复制了它。书中也是这样打的。

4

2 回答 2

5
if (abs(result - 4.0 < .0001))

括号是错误的,你可能的意思是:if (abs(result-4.0) < .0001).

至于为什么它没有编译,标准在 §26.8p8 中确定

除了 中的数学函数的 double 版本之外,C++ 还添加了这些函数的 float 和 long double 重载版本,具有相同的语义。

该表达式(result-4.0 < .0001)产生 a bool,并且没有abs接受bool参数的重载,但是有多个版本abs的参数可以从 隐式转换bool。编译器没有找到比其他转换序列更好的转换序列,因此会出现歧义错误。

于 2012-09-29T02:42:35.943 回答
3

问题显然是线

if (abs(result - 4.0 < .0001))

应该写成

if (abs(result - 4.0) < .0001)

我认为这是一个简单的错字。向本书作者报告错误!

顺便说一句,原始代码在我的系统上编译没有任何问题,给出了预期的结果!也就是说,即使作者测试了代码,他也可能没有注意到它有问题!

还回答了为什么abs()需要这个问题:一些十进制数被四舍五入为一个略小于预期结果的浮点值,而另一些则被四舍五入为稍大的数字。值在哪个方向是圆形的(如果有的话:一些十进制数可以使用二进制浮点数精确表示)有点难以预测。因此,result可能比期望值和差值略大或略小,因此分别为正或负。

于 2012-09-29T02:42:54.727 回答