不到0.1!这是因为双不得不截断近似,由于它的内存有限,导致一个号码是不是0.1。这就是所谓的舍入误差。
舍入误差可以用数学激烈的节目的严重破坏,为数学运算复合误差。下面的程序中,我们使用9个加法运算。
1
2
3
4
5
6
7
8
9
10
|
#include <iostream>
#include <iomanip>
int
main()
{
using
namespace
std;
cout << setprecision(17);
double
dValue;
dValue = 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1;
cout << dValue << endl;
}
|
请注意,错误不再是最后一列就像前面的例子!它已经传播到倒数第二列。当你继续做数学作业,这个错误可能进一步传播,造成实际数字漂移远离用户期望的数量。
浮点数比较
一个程序员喜欢做数字和变量或变量的两个数是否相等的东西。C++提供了一个算子称为相等运算符(= =)正是为了这个目的。例如,我们可以写一段代码这样:
1
2
3
4
5
|
int
x = 5;
// integers have no precision issues
if
(x==5)
cout <<
"x is 5"
<< endl;
else
cout <<
"x is not 5"
<< endl;
|
这个程序将打印“x 5″。
然而,当使用浮点数,你可以如果这两个数字相比是非常接近的得到一些意想不到的效果。考虑:
这个程序打印:
ftotal不是2.468
这样的结果是由于舍入误差。ftotal实际上是被存储为2.4679999,而不是2.468!
出于同样的原因,比较运算符>,>,=,<,<=,可能产生错误的结果,当比较两个浮点数是非常接近的。
结论
总结,你应该记住的浮点数的两件事:
1)提供有限的精度的浮点数。浮动通常提供大约7位有效数字的精度值,和双打提供大约16位有效数字。尝试使用更多的有意义的数字会导致精度损失。(注:占位符零点不算有意义的数字,所以一个数的22000000000,或0.00000033只占2位)。
2)浮点数经常有小的舍入误差。很多时候这些不起眼的因为他们是如此的小,因为数据截断误差传播到输出之前,是不会被删除的部分。不管怎样,对浮点数的比较可能不能达到预期的结果在两个数是接近的。
关系算子部分比较浮点数有更多的细节。