SAP的面试题之一:
如何判断两个浮点数是否相等:
例1:
a=1.000001 b=1.0两个数,一般情况下会认为两者相等。一般我们会认为写出代码:
#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;
int main()
{
double a,b;
cout<<"请输入浮点数a和b"<<endl;
const double eps=1.0e-6;//设置绝对误差阈值,当两个数绝对误差很小很小的时候,就认为两者相等;
while(cin>>a>>b)
{
if(fabs(a-b)<=eps)
{
cout<<"a和b相等"<<endl;
}
else
{
cout<<"a和b不相等"<<endl;
}
}
return 0;
}
结果:
例2:
a=1000.0001 b=1000.000时,
显然按照上面的程序,两者并不相等,但是按照相对误差(1000.001-1000.00)/1000.000=1.0e-6;所以应该认为两者相等;
于是我们用相对误差改写代码:
#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;
int main()
{
double a,b;
cout<<"请输入浮点数a和b"<<endl;
const double eps=1.0e-6;//设置绝对误差阈值,当两个数绝对误差很小很小的时候,就认为两者相等;
while(cin>>a>>b)
{
if(fabs(a-b)<=eps*fabs(a))//用相对误差计算,看两者是否相等;
{
cout<<"a和b相等"<<endl;
}
else
{
cout<<"a和b不相等"<<endl;
}
}
return 0;
}
两者相等;
但是当输入:
a=0.0000 b=0.0001时,代码//;if(fabs(a-b)<=eps*fabs(a))右端为0;左端不为0;显然是不相等的,所以仍然不能全面判断两个浮点数是否相等;
比较好的方法是将相对误差和绝对误差相结合:
#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;
bool IsEqual(float a,float b ,const double eps,const double releps);
int main()
{
double a,b;
cout<<"请输入浮点数a和b"<<endl;
bool flag=true;
while(cin>>a>>b)
{
double eps=10e-9;//设置绝对误差阈值,当两个数绝对误差很小很小的时候,就认为两者相等;
double releps=10e-4;//设置相对误差阈值,当两个数的相对误差很小的时候,认为相等
flag=IsEqual(a,b,eps,releps);
if(flag==true)
{
cout<<"a b 相等"<<endl;
}
else
{
cout<<"a b不等"<<endl;
}
}
return 0;
}
bool IsEqual(float a,float b , double eps,double releps)
{
if(a==b)
{
return true;
}
if(fabs(a-b)<eps)
{
return true;
}
if(fabs(a-b)<=releps*fabs(a))
{
return true;
}
}
结果
如何判断一个浮点数是否为0:
规则:
不可将浮点变量用“==”或“!=”与任何数字比较。
千万要留意,无论是float 还是double 类型的变量,都有精度限制。所以一定要
避免将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”形式。
假设浮点变量的名字为x,应当将
if (x == 0.0) // 隐含错误的比较
转化为
if ((x>=-EPSINON) && (x<=EPSINON))
其中EPSINON 是允许的误差(即精度)。