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