c ++中

时间:2016-05-10 17:55:46

标签: c++ double

我想计算三个双数的总和,我希望得到1.

double a=0.0132;
double b=0.9581;
double c=0.0287;
cout << "sum= "<< a+b+c <<endl;
if (a+b+c != 1)
cout << "error" << endl;

总和等于1,但我仍然得到错误!我也尝试过:

cout<< a+b+c-1

它给了我-1.11022e-16

我可以通过将代码更改为

来解决问题

if (a+b+c-1 > 0.00001) cout << "error" << endl;

它有效(没有错误)。负数如何大于正数以及为什么数字不能加1? 也许这是基本的总和和下溢/溢出,但我非常感谢你的帮助。 谢谢

2 个答案:

答案 0 :(得分:3)

有理数是无限精确的。计算机是有限的 精确度损失是计算机编程中众所周知的问题 真正的问题是,你如何解决它?

在比较浮点数时,请考虑使用近似函数。

#include <iostream>
#include <cmath>
#include <limits>
using namespace std;

template <typename T>
bool ApproximatelyEqual(const T dX, const T dY)
{
    return std::abs(dX - dY) <= std::max(std::abs(dX), std::abs(dY))
    * std::numeric_limits<T>::epsilon();
}

int main() {
    double a=0.0132;
    double b=0.9581;
    double c=0.0287;

    //Evaluates to true and does not print error.
    if (!ApproximatelyEqual(a+b+c,1.0)) cout << "error" << endl;
}

答案 1 :(得分:2)

C ++中的浮点数具有二进制表示。这意味着大多数数字只能用几位数的小数部分精确表示,不能用浮点数精确表示。这就是你的错误所在。

一个例子:0.1(十进制)是二进制的周期分数:

0.000110011001100110011001100...

因此,不能用二进制编码用任意数量的位来表示它。

为了避免这种类型的错误,您可以使用某些特殊库支持的BCD(二进制编码的十进制)数字。缺点是计算速度较慢(不直接由CPU支持)和稍高的内存使用率。

另一种选择是用一般分数表示数字,并将分子和denomiator存储为单独的整数。