zoukankan      html  css  js  c++  java
  • OpenJudge计算概论-求一元二次方程的根【含复数根的计算、浮点数与0的大小比较】

    /*======================================================================
    求一元二次方程的根
    总时间限制: 1000ms 内存限制: 65536kB
    描述
    利用公式x1 = (-b + sqrt(b*b-4*a*c))/(2*a), x2 = (-b - sqrt(b*b-4*a*c))/(2*a)求一元二次方程ax^2 + bx + c =0的根,其中a不等于0。
    输入
    第一行是待解方程的数目n。 
    其余n行每行含三个浮点数a, b, c(它们之间用空格隔开),分别表示方程ax2 + bx + c =0的系数。
    输出
    输出共有n行,每行是一个方程的根:
    若是两个实根,则输出:x1=...;x2 = ...
    若两个实根相等,则输出:x1=x2=...
    若是两个虚根,则输出: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
    提示
    1、需要严格按照题目描述的顺序求解x1、x2。
    2、方程的根以及其它中间变量用double类型变量表示。
    3、函数sqrt()在头文件math.h中。
    4、要输出浮点数、双精度数小数点后5位数字,可以用下面这种形式: 
    
    printf("%.5f", num);
    
    注意,在使用Java做此题时,可能会出现x1或x2等于-0的情形,此时,需要把负号去掉
    ========================================================================*/
     1 #include<stdio.h>
     2 #include<math.h>
     3 int comparToZero(double x);//当x与0之差的绝对值小于0.00001(即:1e-5)时 认为x等于0 
     4 int main()
     5 {
     6     int n,i;
     7     double a,b,c,delt;
     8     double x1,x2,real,image;
     9     freopen("222.in","r",stdin);
    10     scanf("%d",&n);
    11     for(i=0;i<n;i++)
    12     {
    13         scanf("%lf%lf%lf",&a,&b,&c);
    14         delt=b*b-4*a*c;
    15         if(comparToZero(delt)==1)   //if(delt>0)
    16         {
    17             x1=(-b+sqrt(delt))/2/a;
    18             x2=(-b-sqrt(delt))/2/a;
    19             if(comparToZero(x1)==0)
    20                 x1=0;
    21             if(comparToZero(x2)==0)
    22                 x2=0;
    23             printf("x1=%.5lf;x2=%.5lf
    ",x1,x2);
    24         }
    25         else if(comparToZero(delt)==0)   //if(delt==0)
    26         {
    27             x1=-b/2/a;
    28             if(comparToZero(x1)==0)
    29                 x1=0;
    30             printf("x1=x2=%.5lf
    ",x1);
    31         }
    32         else   //delt<0
    33         {
    34             delt=sqrt(-delt);
    35             real=-b/2/a;
    36             image=delt/2/a;
    37             if(comparToZero(real)==0) real=0;
    38             if(comparToZero(image)==0) image==0;
    39             printf("x1=%.5lf+%.5lfi;x2=%.5lf-%.5lfi
    ",real,image,real,image);
    40         }
    41     }
    42     return 0;
    43 }
    44 int comparToZero(double x)//当x与0之差的绝对值小于0.00001(即:1e-5)时 认为x等于0 
    45 {
    46     /*if(x>0)  return 1;
    47     else if(x<0)  return -1;
    48     else  return 0;*/  
    49     //上面的写法会出现浮点数计算精度的误差 。需要改用下面的方法来比较浮点数x和0之间的大小关系。 
    50     if((x-0)>1e-5) return 1;
    51     else if((x-0)<-(1e-5)) return -1;
    52     else return 0;
    53 }
    54 /*==============================================================================
    55 实数运算中,经常需要判断实数x和y是否相等。编程者往往把判断的条件简单设成x==y或者y-x==0.
    56 实际上,这种写法是有失偏颇的,可能会产生精度误差。
    57 避免精度误差的办法就是设置一个精度常量delta。
    58 若y-x的实数值与0之间的区间长度小于delta,则认为x和y相等,这样就可以把误差控制在delta范围内。
    59 显然,判断实数x和y是否相等的条件应设成|x-y|<=delta。下面是一个实例。
    60 ===============================================================================*/

    这个题目需要注意的两个地方:

    /*==========================================
    这个题需要注意的地方:
    1. 当一个数如果在(-0.000005,0)之间,输出精确到小数点后5位,
    就是0而不是期望的某个小数0.00……,所以需要判断处理一下输出数据

    2. 浮点数无法和0比较,浮点数本身不是一个精确值,
    可以用fabs(x-0)<1e-5来比较(这里精确度为5)
    ============================================*/

  • 相关阅读:
    nginx反向代理编译异常
    TCP/ip协议栈之内核调优
    Tcp之异常
    Codeforces Round #584
    Codeforces Round #588 (Div. 2)
    Codeforces Round #587 (Div. 3) F
    P4587 [FJOI2016]神秘数 主席树
    P4559 [JSOI2018]列队 主席树
    P4098 [HEOI2013]ALO 可持久化01trie
    4771: 七彩树 主席树
  • 原文地址:https://www.cnblogs.com/huashanqingzhu/p/3462619.html
Copyright © 2011-2022 走看看