5 c++ for-loop floating-accuracy
我在32位Ubuntu 8.04上使用gcc 4.2.4编译了一个简单的C++程序.它有一个for-loop,其中一个double变量从零增加到一个具有一定步长的一个.当步长是0.1,行为是我所期望的.但是当步长为'0.05'时,循环退出0.95.谁能告诉我为什么会这样?输出遵循以下源代码.
#include <iostream>
using namespace std;
int main()
{
double rangeMin = 0.0;
double rangeMax = 1.0;
double stepSize = 0.1;
for (double index = rangeMin; index <= rangeMax; index+= stepSize)
{
cout << index << endl;
}
cout << endl;
stepSize = 0.05;
for (double index = rangeMin; index <= rangeMax; index+= stepSize)
{
cout << index << endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
OUTPUT
sarva@savija-dev:~/code/scratch$ ./a.out
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
0
0.05
0.1
0.15
0.2
0.25
0.3
0.35
0.4
0.45
0.5
0.55
0.6
0.65
0.7
0.75
0.8
0.85
0.9
0.95
sarva@savija-dev:~/code/scratch$
Run Code Online (Sandbox Code Playgroud)
Mot*_*tti 18
使用浮点值时,并非每个值都可以准确表示,0.95+0.05 > 1因为0.95值不能完全表示double.
了解维基百科对浮点精度的看法.
如果你看一下IEEE浮点转换器,你会看到0.9564位浮点(double)的值是0-01111111110-1110011001100110011001100110011001100110011001100110通过在浮点计算器中输入这个值得到的值,0.95000016并且加上0.05它会超过1.0标记.
这就是为什么你不应该在循环中使用浮点(或者更一般地将浮点计算的结果与精确值进行比较).
Ann*_*nna 11
通常,当你比较双打时,简单的比较不够好,你应该比较它们"达到精度".即:
if ( fabs(double1-double2) < 0.0000001 ) {
do-something
}
Run Code Online (Sandbox Code Playgroud)
由于其内部表示,您不应使用==或<=表示双精度数.在最后一步,你会得到0.95000000000000029.相反,您可以使用以下代码:
stepSize = 0.05;
// stepSize/2 looks like a good delta for most cases
for (double index = rangeMin; index < rangeMax+stepSize/2; index+= stepSize)
{
cout << index << endl;
}
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请阅读每位计算机科学家应该了解的关于浮点运算的内容.
| 归档时间: |
|
| 查看次数: |
12521 次 |
| 最近记录: |