关于精度处理(浮点误差)的总结

    今天做题遇到了一个题目,怎么也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));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

永远的水面

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

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

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

打赏作者

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

抵扣说明:

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

余额充值