關於精度處理(浮點誤差)的總結

    今天做題遇到了一個題目,怎麼也ac不了,最後發現是精度(浮點誤差)的問題。

衆所周知,浮點數無論是double還是float都有精度限制,但它能存儲多少有效位數不代表它能精確到這些有效位數。比方說,你輸入一個1,float型可能存了1.000000001,也可能存了0.999999999,他們在輸出時都表示爲1,但在計算時不同。
比方說下述代碼二者結果一個爲0.00,一個爲0.01。
這種影響在0時表現尤爲明顯,十分影響a==0或a==b的判斷。
針對這種問題,我們可以設一個eps=1e-6(或者1e-8)用來檢驗,比方說:
aa-b<-eps a<=b–>eps
a==b–>abs(a-b)

int main()
{
    printf("%.2f\n",0.0049);
    printf("%.2f\n",0.0051);
    return 0;
}

cugboj題目1524:解方程
有一個型爲 這裏寫圖片描述的一元二次方程,(a不等於0)你的任務是,編寫一個程序,實現輸入a,b,c三個整數後,輸出方程的解。
input:輸入第一行爲一個正整數N(1<=N<=50),爲測試數據的個數。 接下來N行每行包括三個整數a、b、c。
output:每個輸出佔一行,爲方程的解。 若方程有兩個相等的解,輸出一個即可。 若方程有兩個不等的解,先輸出值大的解,兩解以一個空格隔開。 若方程在實數範圍無解,輸出含虛數的解。
這裏寫圖片描述

附上ac代碼():

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
using namespace std;
#define eps 1e-6
void ergen(int a,int b,int c);
void dangen(int a,int b,int c);
void xugen(int a,int b,int c);
int main()
{
    double n,a,b,c;
    cin>>n;
    while(n--)
    {
        cin>>a>>b>>c;
        if(b*b-4*a*c>eps) ergen(a,b,c);
        else if(b*b-4*a*c<eps&&b*b-4*a*c>-eps) dangen(a,b,c);
        else xugen(a,b,c);
    }
    return 0;
}
void xugen(int a,int b,int c)
{
    double delta=4*a*c-b*b;
    if(b!=0) printf("%.3lf+",-b*1.0/(2*a)+eps);
    printf("%.3lfi ",abs(sqrt(delta)/(2*a))+eps);
    if(b!=0) printf("%.3lf",-b*1.0/(2*a)+eps);
    printf("-%.3lfi\n",abs(sqrt(delta)/(2*a))+eps);
}
void dangen(int a,int b,int c)
{
    printf("%.3lf\n",-b*1.0/(2*a)+eps);
}
void ergen(int a,int b,int c)
{
    double x1=(-b*1.0+sqrt(b*b-4.0*a*c))/(2*a)+eps;
    double x2=(-b*1.0-sqrt(b*b-4.0*a*c))/(2*a)+eps;
    printf("%.3lf %.3lf\n",max(x1,x2),min(x1,x2));
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章