概述
自己一直纠结于浮点类型精度丢失问题,认为浮点类型的相等比较是不靠谱的,写代码时一直不太敢用,导致了很多不必要的麻烦以及WA,所以自己研究了一下。
首先上结论,就是说浮点类型以及浮点数的比较是靠谱的,两个浮点类型,它们所表示的数的大小都是固定的,一比较,大的就大,小的就小,相等的就相等的,不会不靠谱的。浮点数同理。
不靠谱的是精度损失。比如说一个浮点数,保存在一个浮点类型里面。浮点数表示成二进制可能是无限循环小数,而浮点类型的空间又有限,所以只能截尾。所以此时保存在浮点类型里的浮点数就不是原来的那个浮点数了,这就是精度损失,这就是不靠谱。
所以说,只要不保存在浮点类型里,就不会有精度损失,就不会不靠谱。
这也就是为什么大白书P154上说“注意,f的类型是double,有可能会损失精度。解决这个问题,有一种办法是不使用中间变量”的原因了。
那什么时候可以直接比较,什么时候需要用到eps呢?
答案就是如果产生了精度损失(即曾经保存在浮点类型中过),那就最好用eps,否则就要看运气(损失后刚好一样,或者其他原因),看编译器(其实我也不知道不同的编译器会不会不同标准),看数据(如果数据很弱你就混过去了)了。
一些实用技巧:
a>=0 改为 a>-eps
a<=0 改为 a<eps
理论上我觉得UVA 10341是要用eps的,鬼知道你的1存进去后是变大了还是变小了那么一点点然后就算错了呢?
但是事实上存进去后还是1。。。所以没关系了。
一些测试代码供参考
#include<bits/stdc++.h>
using namespace std;
int main()
{
float b=0.000001;
float a=0.000001;
if(a==0.000001) puts("YES");
else puts("NO");
if(a==b) puts("YES");
else puts("NO");
a*=1000000000000;
a/=3;
a/=2;
a/=5;
a/=7;
a/=2.71828;
a*=2.71828;
a*=7;
a*=5;
a*=2;
a*=3;
a/=1000000000000;
if(a==b) puts("YES");
else puts("NO");
a=0.000001;
a=a*1000000000000/3/2/5/7/2.71828*2.71828*7*5*2*3/1000000000000;
if(a==b) puts("YES");
else puts("NO");
return 0;
}
最后
以上就是飘逸铅笔为你收集整理的精度丢失的全部内容,希望文章能够帮你解决精度丢失所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复