精度误差问题与eps

前言

对于精度误差这个词的认识是在看别人写的sqrt函数应用时开始的,现在并没有在这方面遇到过问题,下面的经验是对所看过这一类文章的总结


一、什么是精度误差

比如这里我们用一个double去接收一个六位精度的值,那么前六位数的值一定是固定的,但是六位以后的值由于没有固定的输入将会是任意可能出现的数值。同理我们如果存入0给double在0以后位数的值也都是不确定的,这种不确定位数的值不可控的现象就是精度误差。

二、精度误差事例即解决方法

1、sqrt判断质数

一般的判断质数的代码都是如下的,我一开始也是这么写的。

bool find(int n)
{
	for(int i=2;i<=sqrt(n);i++)
	{
		if(n%i==0)
			return false;
	}
	return true;
}

 但这样的写法其实是不严谨的,比如说我判断9是不是素数,这时候sqrt(9)的值本应该是3,但其实sqrt的返回值是一个浮点数,所以这里的精度误差就可能导致返回值为2.9999999这一类数,从而导致答案的错误,正确的写法应该如下。

bool find(int n)
{
	int sql=(int)sqrt(1.0*n);//1.0*n的目的是  隐式转换成浮点数,开根号后再强制转换成整型 
	for(int i=2;i<=sql;i++)
	{
		if(n%i==0)
			return false;
	}
	return true;
}

2、判断浮点数相等

即使是理论上相同的值,由于是经过不同的运算过程得到的,他们在低几位有可能(一般来说都是)是不同的。这种现象看似没太大的影响,却会一种运算产生致命的影响: ==。注意,C/C++中浮点数的==需要完全一样才能返回true,解决的办法是引进eps,来辅助判断浮点数的相等。

eps缩写自epsilon,表示一个小量,但这个小量又要确保远大于浮点运算结果的不确定量。eps最常见的取值是1e-8左右。引入eps后,我们判断两浮点数a、b相等的方式如下

 这样,我们才能把相差非常近的浮点数判为相等;同时把相差较大(差值大于eps)的数判为不相等。

3、eps解决函数越界

如果sqrt(a), asin(a), acos(a) 中的a是你自己算出来并传进来的,那么就有可能因为浮点误差导致出现错误。如果a本来应该是0的,由于浮点误差,可能实际存储的是一个绝对值很小的负数(比如1e-12),这样sqrt(a)应得0的,直接因a不在定义域而出错。

类似地,如果a本来应该是±1,则asin(a)、acos(a)也有可能出错,对于此种函数,必需事先对a进行校正。

4、eps解决输出问题

这一节都是因为题目要求输出浮点数导致的问题,并且都和四舍五入有关。

现在考虑一种情况,题目要求输出保留两位小数。case的正确答案的精确值是0.005,按理应该输出0.01,但你的结果可能是0.005000000001(恭喜),也有可能是0.004999999999(悲剧),如果按照printf(“%.2lf”, a)输出,那你的遭遇将和括号里的字相同。

解决办法是如果a为正,则输出a+eps, 否则输出a-eps

5、 输入值波动过大

假如一道题输入给一个浮点数a, 1e-20 < a < 1e20。这时候就不要再用1e-8左右作为eps的值了,合理的做法是把eps按照输入规模缩放到合适大小。


总结

在对set进行判重的时候,是不是用==来判重的?经观察,set不是通过==来判断相等的,是通过<来进行的,具体说来,只要a<b 和 b<a 都不成立,就认为a和b相等,可以发现,精度误差问题可以用这个方法或者eps很好的解决的。容易产生较大浮点误差的函数有asin、 acos,所以尽量使用atan2。另外,如果数据明确说明是整数,而且范围不大的话,使用int或者long long代替double都是极佳选择.

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

康来个程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值