zoukankan      html  css  js  c++  java
  • 计算误差——ACM计算几何中的精度问题

    • 浮点数为何会有精度问题

      占字节数 数值范围 十进制精度位数
    float 4 -3.4e-38~3.4e38 6~7
    double 8 -1.7e-308~1.7e308 14~15


    如果内存不是很紧张或者精度要求不是很低,一般选用double。14位的精度(是有效数字位,不是小数点后的位数)通常够用了。注意,问题来了,数据精度位数达到了14位,但有些浮点运算的结果精度并达不到这么高,可能准确的结果只有10~12位左右。那低几位呢?自然就是不可预料的数字了。这给我们带来这样的问题:即使是理论上相同的值,由于是经过不同的运算过程得到的,他们在低几位有可能(一般来说都是)是不同的。这种现象看似没太大的影响,却会一种运算产生致命的影响: ==。恩,就是判断相等。注意,C/C++中浮点数的==需要完全一样才能返回true。来看下面这个例子:

    #include <iostream>
    #include<math.h>
    using namespace std;
    
    int main()
    {
        double a=asin(sqrt(2.0)/2)*4.0;
        double b=acos(-1.0);
        printf("a =%.20lf
    ",a);
        printf("b =%.20lf
    ",b);
        printf("a-b=%.20lf
    ",a-b);
        printf("a==b = %d
    ",a==b);
    
        return 0;
    }
    



    解决办法,引进eps,辅助判断浮点数相等

    • eps(epsilon)
    eps最常见的取值是1e-8左右。引入eps后我们判断两浮点数a,b相等的方式是:

    定义三出口函数:int sgn(double a){ return a< -eps?-1:a< eps?0:1;}

    则各种判断大小的运算都应做如下修改:

    传统意义 修正写法1 修正写法2
    a==b sgn(a-b) ==0 fabs(a -b) <eps
    a!=b sgn(a-b) !=0 fabs(a-b)>eps
    a<b sgn(a-b)<0 a-b<-eps
    a<=b sgn(a-b)<=0 a-b<eps
    a>b sgn(a-b)>0 a-b>eps
    a>=b sgn(a-b)>=0 a-b>-eps
         

    这样才能把相差非常近的浮点数判为相等,相差较大的数判为不等。

    ps:养成好习惯,尽量不要对浮点数用==判断。修正写法2中就没有等号


  • 相关阅读:
    加入创业公司有什么利弊
    Find Minimum in Rotated Sorted Array II
    Search in Rotated Sorted Array II
    Search in Rotated Sorted Array
    Find Minimum in Rotated Sorted Array
    Remove Duplicates from Sorted Array
    Spiral Matrix
    Spiral Matrix II
    Symmetric Tree
    Rotate Image
  • 原文地址:https://www.cnblogs.com/bryce1010/p/9387316.html
Copyright © 2011-2022 走看看