习题2-4 求一元二次方程的根 POJ 2707(精度问题)

Note:

本题有三个易错点,均标注在代码中

1.精度必须用double型

2.不能delta==0时才认为x1==x2。应当delta小于一个较小数字时,fabs(delta) < 1e-8即认为没有后半部分

3.%.5f 会将 -0.000001变为-0.00000(负零),需要纠正为0.00000

问题描述:

利用公式

x1 = (-b + sqrt(b*b-4*a*c))/(2*a)

x2=(-b-sqrt(b*b-4*a*c))/(2*a)

求一元二次方程    ax2+bx+c=0 的根,其中  a!=0

 

输入数据:

  第一行是待解方程的数目n。其余n行每行包含三个浮点数a、b、c(它们之间用空格隔开),分别表示方程ax2+bx+c=0

的系数。

 

输出要求:

输出共有n行,每行是一个方程的根。

(1)若是两个实根,则输出:x1=...; x2=...。

(2)若两个实根相等,则输出:x1=x2=...。

(3)若是两个虚根,则输出:x1=实部+虚部i;x2=实部-虚部i

所有实数部分要求精确到小数点后5位,数字、符号之间没有空格。

x1和x2的顺序:x1的实部 > x2 的实部 || (x1的实部==x2的实部&&x1的虚部>=x2的虚部)

 

输入样例:

3
1.0 3.0 1.0
2.0 -4.0 2.0
1.0 2.0 8.0

输出样例:

x1=-0.38197; x2=-2.61803
x1=x2=1.00000
x1=-1.00000+2.64575i;x2=-1.00000-2.64575i
#include 
#include 
#include 
using namespace std;
 int main()
 {
    int n;
    cin >> n;
    while (n--)
    {
        double a, b, c;//易错1,必须用double 
        double x1, x2;
        cin >> a >> b >> c;
        double delta = b*b-4*a*c;
        if (delta > 0)
        {
            x1 = (-b + sqrt(delta))/(2*a);
            x2 = (-b - sqrt(delta))/(2*a);
            printf("x1=%.5f;x2=%.5f\n", x1, x2);
        }
        else if (fabs(delta) < 1e-6)// 易错2,绝对值小于一个很小的数字0.00000001即当作0 
        {
            x1 = -b / (2 * a);
            printf("x1=x2=%.5f\n", x1);
        }
        else
        {
            delta = 0 - delta;// 易错3 ,取反 
            double p = -b / (2 * a);
            double q = sqrt(delta) / (2 * a);
            //.5f 会将 -0.000001变为-0.00000(负零),需要纠正为0.00000
            if (fabs(p) < 1e-6) p = 0.0;//易错4, 检测负0 
            printf("x1=%.5f+%.5fi;x2=%.5f-%.5fi\n", p, q , p, q);
        }
    }
    return 0;
}
 

 

你可能感兴趣的:(算法基础与在线实践,算法基础,模拟)