就剩一个1 -0.4 0.04怎么都过不了

#include
#include
int main()
{
double a,b,c,d,x,x1,x2;

scanf("%lf %lf %lf",&a,&b,&c);
d=b*b-4*a*c;

if(a==0) 
{
    if(b!=0) 
        {
            if((-c)/b!=-0)  printf("x = %g",(-c)/b);
            else if((-c)/b==-0) printf("x = 0");
            else printf("x = %g",(-c)/b);
        }
        
    else if(b==0&&c!=0) printf("无解");
    else if(b==0&&c==0) printf("无穷多解");
}
else if(a!=0)
{
   if(d>=0)
    {
        x1=(-b+sqrt(d))/(2*a);x2=(-b-sqrt(d))/(2*a);
        if(x1==x2) 
        {
            x1=(-b)/(2*a);
            if(x1==0) printf("x1 = x2 = 0");
            else printf("x1 = x2 = %g",x1);
        }
         else if(x1!=x2) 
        {
             if(x1==0) printf("x1 = 0, x2 = %g",x2);
                else if(x2==0) printf("x1 = %g, x2 = 0",x1);
             else  printf("x1 = %g, x2 = %g",x1,x2);
        }
    }
   
    else if(d<0) 
    {
        x1=(-b)/(2*a);    x2=fabs(sqrt(-d)/(2*a));
        if(x1==0)
        {
            
            printf("x1 = %g+%gi, x2 = %g-%gi",0,x2,0,x2);
            
        }
        else printf("x1 = %g+%gi, x2 = %g-%gi",x1,x2,x1,x2);
        
    }
}
return 0;

}

最后那个怎么做出来都是x1=0.2, x2=0.2

if(x1==x2)不合适,改为 if(fabs(x1-x2) < 1e-6) 浮点数最好不要直接判断相等,由于误差可能会不相等,应该计算两者差值的绝对值小于一个很小数来判定相等

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/203315
  • 这篇博客你也可以参考下:苹果4.3被拒问题;教你如何解决常见代码层次的4.3被拒问题
  • 除此之外, 这篇博客: 你别耍我,0.1+0.2竟然不等于0.3?(浮点数的二进制表示)中的 单精度浮点数 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    接下来我们先聊聊单精度浮点数,32bit位是按照下图所示的3段来存储的:

    • 1)首先为了区分正负数,用最高的bit位表示其符号S,如果是0表示为正数,如果为1表示为负数。
    • 2)接下来的8bit是其指数E,因为指数也有正负之分,但是这时并没有在这8bit指数位中用一个bit表示指数的符号,而是采用偏移127的方式,也就是该8bit表示的数值减去127得到的就是指数,换个说法就是实际的指数加上127得出该8bit的值,比如指数为1就用1+127=0x80=0b10000000表示,如果是-10就用-10+127=0x75=0b01110101表示。
    • 3)剩下的23bit就用来表示其有效值M,也就是小数点后面的数。需要注意的是小数点的位置问题,小数点总是取在第一个1后面,比如1010.01应该将小数点左移3位得到1.01001*p3,移位的过程同时得出指数值和有效数值。在表示有效数值时,小数点前面的数值1总是被省略掉,这样节省下来的1个bit可以用来表示小数点后更多一位的有效值。
    • 4)处理舍入问题,因为转换为二进制小数后可能是无限小数,或者实际的位数大于23位,所以需要根据小数点后面的第24位决定是舍去还是向23位进1,这里遵循就近舍入原则,A)、如果第25位及以后还存在非0的数值,第24位如果为1,向23位进1,如果第24位为0,则舍去后面的值;B)、如果第25位及以后全部为0,则遵循偶数原则,保证第23位为0,具体做法是:第24位如果为1且第23位为1,则向23位进1;第24位为1且第23位为0,则舍去;第24位如果为0也舍去。

    以上面的10.3为例,用二进制表示为1010.0100110011001100110011001……,

    • 1)首先符号为正所以符号S=0
    • 2)然后是取有效值,首先移位小数点保证小数点前只有一个1,所以需要将小数点左移3位,因为向左移动了3位所以指数为+3,得到移位后的小数为:1.0100100110011001100110011001……(E=3),同时得到指数位是3+127=130=0x82=0b1000 0010‬,所以指数E=1000 0010‬;
    • 3)小数点后面1-23位是01001001100110011001100
    • 4)再考虑舍入问题,第24bit为1且后面仍然有非0的数值,所以向23位进1,这样最终的有效值M=01001001100110011001101,这样10.3用二进制表示为:01000 001001001001100110011001101‬,16进制表示为0x4124 CCCD。

    前面是手动计算的结果,我们可以用一个C语言的联合体来验证下计算结果是否正确,首先定义了一个联合体的数据类型包含2个成员,一个是32bit长度的无符号整型,一个是单精度浮点型,赋值其中的浮点类型,再用16进制的方法打印其无符号整型值,可以方便观察二进制数值:

    //juzicode.com / VX:桔子code  //vs2015
    #include "stdio.h"
    typedef union {
        unsigned int i;
        float f;
    }fu32;
    int main(void)
    {
        fu32 fu1;
        fu1.f = 10.3f;
        printf("fu1.f=%f\n", fu1.f);
        printf("fu1.i=0x%x\n", fu1.i);
        return 0;
    }
    -----运行结果:
    fu1.f=10.300000
    fu1.i=0x4124cccd

    这里得到的结果为0x4124cccd,和前面手动计算的结果是一样的。

    下面再来看一个负数的浮点数-0.2,用乘2取整的方法计算其二进制形式:

    • 0.2*2=0.4 取整为0
    • 0.4*2=0.8 取整为0
    • 0.8*2=1.6 取整为1
    • 0.6*2=1.2 取整为1
    • 0.2*2=0.4 取整为0,接下来是无限循环
    • ……

    最后得到的小数为-0.001100110011001100110011001100110011……,

    • 1)符号S=1
    • 2)因为要保证小数点前一位是1,所以小数点要向后移动3位,变成-1.100110011001100110011001100110011……(E=-3)所以指数为-3指数E=-3+127=0x7C=0b01111100;
    • 3)小数点后面1-23位是10011001100110011001100,第24位为1,且后面有非0的数值,这样在第23位上有进位,所以有效数M=10011001100110011001101;
    • 4)最后组合起来就是0b10111110010011001100110011001101=0xBE4C CCCD;

    同样可以用联合体的方式打印其十六进制数值进行验证:

    //juzicode.com / VX:桔子code  //vs2015
    #include "stdio.h"
    typedef union {
        unsigned int i;
        float f;
    }fu32;
    int main(void)
    {
        fu32 fu1;
        fu1.f = -0.2f;
        printf("fu1.f=%f\n", fu1.f);
        printf("fu1.i=0x%x\n", fu1.i);
        return 0;
    }
    -----运行结果:
    fu1.f=-0.200000
    fu1.i=0xbe4ccccd

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^