我是靠谱客的博主 飘逸铅笔,最近开发中收集的这篇文章主要介绍精度丢失,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

自己一直纠结于浮点类型精度丢失问题,认为浮点类型的相等比较是不靠谱的,写代码时一直不太敢用,导致了很多不必要的麻烦以及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;
}


最后

以上就是飘逸铅笔为你收集整理的精度丢失的全部内容,希望文章能够帮你解决精度丢失所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(29)

评论列表共有 0 条评论

立即
投稿
返回
顶部