为什么这块输出的是 NAN (Not a Number)?

Why this piece is outputting NAN (Not a Number)?

我正在尝试使用 STL 实现最近对问题,但我遇到了一个问题,尤其是在基本条件本身!

如果我尝试打印 (1,1) 和 (0,0) 之间的距离,这段代码 returns nan 会起作用。预期的输出至少是一些数字,我的意思是我认为我没有把它搞砸但它不起作用!!!!!

注意:我已经尝试使用测试距离 distance( make_pair(make_pair(1,1),make_pair(0,0))) 并给出正确的输出。我想还有一些我想念的东西

基本条件(注意我过度使用了对,但这很好):

if(R-L+1<=3)
{
    int i,j;
    double Temp=1000000.00;
    pair < pair < int , int > , pair < int  , int > >ret;
    for(i=L;i<R;++i)
    {
        for(j=i+1;j<=R;++j)
        {
            pair < pair < int , int > , pair < int , int > >PEE=make_pair(X[i],X[j]);
            cout<<distance(PEE)<<" ";//This statement outputs nan!!
            if(distance(PEE)<Temp)
            {
                ret=PEE;
                Temp=distance(ret);
            }

        }
    }

    return ret;
}

那个 cout 语句不会给出正确的输出!!

这里,ret 是 return (Closest pair) 的点。存储距离的温度。

整个函数:

pair < pair < int , int > , pair < int , int > > Divide(int L,int R)
{
    if(R-L+1<=3)
    {
        int i,j;
        double Temp=1000000.00;
        pair < pair < int , int > , pair < int  , int > >ret;
        for(i=L;i<R;++i)
        {
            for(j=i+1;j<=R;++j)
            {
                pair < pair < int , int > , pair < int , int > >PEE=make_pair(X[i],X[j]);
                cout<<distance(PEE)<<" ";
                if(distance(PEE)<Temp)
                {
                    ret=PEE;
                    Temp=distance(ret);
                }

            }
        }

        return ret;
    }

    int M=(R+L)/2;
    pair < pair < int , int > , pair < int , int > > P1=Divide(L,M),Chota;
    pair < pair < int , int > , pair < int , int > > P2=Divide(M+1,R);
    double Delta;
    if(distance(P1)<distance(P2))
        {
            Delta=distance(P1);
            Chota=P1;
        }
    else
        {
            Delta=distance(P2);
            Chota=P2;
        }
    pair < pair < int , int > , pair < int , int > > P3=Merge(L,R,Delta);
    if(distance(P3)<distance(Chota))
        return P3;
    else
        return Chota;

}

距离函数:

 double distance(pair < pair < int , int > , pair < int , int > > P)
{
    return (double)sqrt(SQUARE(P.first.first-P.second.first)+SQUARE(P.first.second-P.second.second));
}

SQUARE 的宏:

#define SQUARE(x)  (x*x)
#define MOD(X)  (X>0?X:-1*X)

现在整个程序以备不时之需!

#include<bits/stdc++.h>
#define SQUARE(x)  (x*x)
#define MOD(X)  (X>0?X:-1*X)
using namespace std;
pair < int , int > P[5000+1],X[5000+1],Y[5000+1];

 double distance(pair < pair < int , int > , pair < int , int > > P);

 pair < pair < int , int > , pair < int , int > > Merge(int L , int R, double Delta)
 {
     pair < int , int > Copy[R-L+1],Temp=X[(R+L)/2];
     int i,j,k=0;
     for(i=L;i<=R;++i)
         if(MOD(Temp.first-Y[i].first)<=Delta+1e-9)
            Copy[k++]=Y[i];
     const int Size=k;
     double Dis=10000000;
     pair < pair < int , int > , pair < int , int > > ret;
     for(i=0;i<Size;++i)
     {
         for(j=i+1;j<=i+7 && j<Size; ++j)
            {
                if(distance(make_pair(Copy[i],Copy[j]))<Dis)
                   {
                        ret=make_pair(Copy[i],Copy[j]);
                        Dis=distance(ret);
                   }
            }
     }
     return ret;
 }

pair < pair < int , int > , pair < int , int > > Divide(int L,int R)
{
    if(R-L+1<=3)
    {
        int i,j;
        double Temp=1000000.00;
        pair < pair < int , int > , pair < int  , int > >ret;
        for(i=L;i<R;++i)
        {
            for(j=i+1;j<=R;++j)
            {
                pair < pair < int , int > , pair < int , int > >PEE=make_pair(X[i],X[j]);
                cout<<distance(PEE)<<" ";
                if(distance(PEE)<Temp)
                {
                    ret=PEE;
                    Temp=distance(ret);
                }

            }
        }

        return ret;
    }

    int M=(R+L)/2;
    pair < pair < int , int > , pair < int , int > > P1=Divide(L,M),Chota;
    pair < pair < int , int > , pair < int , int > > P2=Divide(M+1,R);
    double Delta;
    if(distance(P1)<distance(P2))
        {
            Delta=distance(P1);
            Chota=P1;
        }
    else
        {
            Delta=distance(P2);
            Chota=P2;
        }
    pair < pair < int , int > , pair < int , int > > P3=Merge(L,R,Delta);
    if(distance(P3)<distance(Chota))
        return P3;
    else
        return Chota;

}

bool cmp(pair < int , int > A , pair < int , int > B){return A.second<B.second;}
int main()
{


    int N,i;
    scanf("%d",&N);
    for(i=0;i<N;++i)
        {
            scanf("%d%d",&P[i].first,&P[i].second);
            Y[i]=X[i]=P[i];
        }

    sort(X,X+N);
    sort(Y,Y+N,cmp);
    Divide(0,N-1);
    return 0;
}

 double distance(pair < pair < int , int > , pair < int , int > > P)
{
    return (double)sqrt(SQUARE(P.first.first-P.second.first)+SQUARE(P.first.second-P.second.second));
}
#define SQUARE(x)  (x*x)

可能会产生负值,例如

cout << SQUARE(-1-2) << endl;

-1 - 2*-1 - 2 中得到解析并生成 -1

最好避免使用宏,但是如果你使用这个,就制作它

#define SQUARE(x)  ((x)*(x))

运行 这通过 g++ -E 的预处理步骤非常清楚地显示了您的宏使用导致的问题。预处理前:

 double distance(pair < pair < int , int > , pair < int , int > > P)
{
    return (double)sqrt(SQUARE(P.first.first-P.second.first)+SQUARE(P.first.second-P.second.second));
}

预处理后:

double distance(pair < pair < int , int > , pair < int , int > > P)
{
return (double)sqrt((P.first.first-P.second.first*P.first.first-P.second.first)+(P.first.second-P.second.second*P.first.second-P.second.second));
}

这几乎肯定不是您想要的。正如您所看到的,这会产生对 sqrt 的否定论证,然后它将为您提供您所看到的 NaN。

要正确编写宏,您可以查看 AlexD 的答案,但老实说,我认为这里更好的方法是不使用宏,而只使用标准库中的正方形函数和 abs 函数。