如何比较if语句中的double变量

时间:2018-03-21 10:58:26

标签: c if-statement double comparison

当我试图比较这些双打时,它似乎无法正常工作

这就是:(这正是我的问题)

#include <stdio.h>
#include <math.h>

int main () {
    int i_wagen;
    double dd[20];
    dd[0]=0.;
    dd[1]=0.;
    double abstand= 15.;
    double K_spiel=0.015;
    double s_rel_0= K_spiel;
    int i;

    for(i=1; i<=9; i++)
    {
        i_wagen=2*(i-1)+2;
        dd[i_wagen]=dd[i_wagen-1]-abstand;
        i_wagen=2*(i-1)+3;
        dd[i_wagen]=dd[i_wagen-1]-s_rel_0;
    }
    double s_rel=dd[3-1]-dd[3];

   if((fabs(s_rel) - K_spiel) == 0.)
   {
       printf("yes\n");
   }
   return(0);
}

执行程序后,它不会打印是。

3 个答案:

答案 0 :(得分:0)

您将 x 与两个不同的矩阵条目进行比较:第一个是将 x 与coeff [0] [0] 进行比较,第二个是coeff [0] [1] 。因此,如果 x 大于coeff [0] [0] 且小于或等于coeff [0] [1] ,程序将执行最后的其他分支。您可能希望将x与两个if语句中的相同矩阵条目进行比较。在这种情况下,最后一个分支将是无用的,因为三个案例中的一个(小于,等于或大于)必须是真的。

答案 1 :(得分:0)

  

如何比较if语句中的双变量?

考虑浮点数的双重表示的有限精度!

您的问题很简单,并在Is floating point math broken?

中介绍

浮点运算不准确。给定数字的表示可能不准确。

对于标准binary64格式的0.1,表示可以完全写为0.1000000000000000055511151231257827021181583404541015625

双精度(双精度)仅为{1}}个有效位,52位指数和11符号位。 C中的浮点数使用IEEE 754编码。

查看程序的输出以及您为接近1的变量而定居的可能修复:

0.0

输出:

#include <stdio.h>
#include <math.h>

#define PRECISION  1e-6

int main (void) {

    int i_wagen;
    double dd[20];

    dd[0]=0.;
    dd[1]=0.;

    double abstand= 15.;
    double K_spiel=0.015;

    double s_rel_0= K_spiel;
    int i;

    for(i=1; i<=9; i++)
    {
        i_wagen = 2*(i-1)+2;

        dd[i_wagen] = dd[i_wagen-1]-abstand;
        i_wagen = 2*(i-1)+3;

        dd[i_wagen] = dd[i_wagen-1] - s_rel_0;
    }

    double s_rel = dd[3-1]-dd[3];

    printf(" s_rel %.16f K_spiel %.16f  diff  %.16f \n" , s_rel, K_spiel, ((fabs(s_rel) - K_spiel)) );

    if((fabs(s_rel) - K_spiel) == 0.0) // THIS WILL NOT WORK!
    {
       printf("yes\n");
    }

    //  Settle down for being close enough to 0.0     
    if( fabs( (fabs(s_rel) - K_spiel)) < PRECISION)
    {      
       printf("yes!!!\n");
    }

    return(0);
}

答案 2 :(得分:0)

首先,语句中使用dd[i_wagen-1]

dd[i_wagen]=dd[i_wagen-1]-abstand;

未初始化。代码将运行,但会产生不可预测的结果。 要初始化,您可以使用:

double dd[20]={0}; //sufficient

或可能

double dd[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //explicit, but not necessary

转到你的实际问题,这一切都归结为这个陈述:

if((fabs(s_rel) - K_spiel) == 0.)

您已将K_spiel初始化为0.015。此时,您的执行流s_rel似乎接近0.015。但它实际上更接近0.0150000000000006。所以比较失败了。

常用的一个技巧是定义一个epsilon值,并使用它来确定两个浮点值之间的差异是否足够小以满足您的目的:

The Art of Computer Programming ,以下代码段使用此方法,并且适用于您的特定示例:(警告: Read why this approach will not work for all floating point related comparisons. )< / p>

bool approximatelyEqual(float a, float b, float epsilon)
{
    return fabs(a - b) <= ( (fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * epsilon);
}

所以更换一行:

if((fabs(s_rel) - K_spiel) == 0.)

if(approximatelyEqual(s_rel, K_spiel, 1e-8)