c++如何判断两个浮点数相等或者大小问题

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 是允许的误差(即精度)。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值