#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;

struct point
{
    double x;
    double y;
    double d;
};

double getMax( double a, double b )
{
    if( a > b )
        return a;
    else
        return b;
}

double getMin( double a, double b )
{
    if( a < b )
        return a;
    else
        return b;
}

double twopointsDistance( double x1, double y1, double x2, double y2 )
{
    return sqrt( ( x2 - x1 ) * ( x2 - x1 ) + ( y2 - y1 ) * ( y2 - y1 ) );
}

bool Intersection( double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3 )
{
    double a, b, c, d, x, y;
    a = x1 - x0;
    b = y1 - y0;
    c = x3 - x2;
    d = y3 - y2;

    if( a == 0 )
    {
        if( c == 0 )
        {
            if( x0 != x2 || x0 == x2 && getMax( y2, y3 ) < getMin( y0, y1 ) || x0 == x2 && getMax( y0, y1 ) < getMin( y2, y3 ) )
                return false;
            else
                return true;
        }
        else if( d == 0 && getMin( y0, y1 ) <= y2 && y2 <= getMax( y0, y1 ) && getMin( x2, x3 ) <= x0 && x0 <= getMax( x2, x3 ) )
            return true;
        else if( d == 0 )
            return false;
        else
        {
            x = x0;
            y = d * x0 / c + y2 - d * x2 / c;
            if( getMin( x2, x3 ) <= x && x <= getMax( x2, x3 ) && getMin( y0, y1 ) <= y && y <= getMax( y0, y1 ) )
                return true;
            else
                return false;
        }
    }
    else if( b == 0 )
    {
        if( c == 0 && getMin( x0, x1 ) <= x2 && x2 <= getMax( x0, x1 ) && getMin( y2, y3 ) <= y0 && y0 <= getMax( y2, y3 ) )
            return true;
        else if( c == 0 )
            return false;
        else if( d == 0 )
        {
            if( y0 != y2 )
                return false;
            else
                if( getMin( x0, x1 ) <= getMin( x2, x3 ) && getMin( x2, x3 ) <= getMax( x0, x1 ) || getMin( x2, x3 ) <= getMin( x0, x1 ) && getMin( x0, x1 ) <= getMax( x2, x3 ) )
                    return true;
                else
                    return false;
        }
        else
        {
            x = ( y0 - y2 + d * x2 / c ) / ( d / c );
            y = y0;
            if( getMin( x0, x1 ) <= x && x <= getMax( x0, x1 ) && getMin( y2, y3 ) <= y && y <= getMax( y2, y3 ) )
                return true;
            else
                return false;
        }
    }
    else if( c == 0 )
    {
        x = x2;
        y = b * x / a + y0 - b * x0 / a;
        if( getMin( x0, x1 ) <= x && x <= getMax( x0, x1 ) && getMin( y2, y3 ) <= y && y <= getMax( y2, y3 ) )
            return true;
        else
            return false;
    }
    else if( d == 0 )
    {
        x = ( y2 - y0 + b * x0 / a ) / ( b / a );
        y = y2;
        if( getMin( x2, x3 ) <= x && x <= getMax( x2, x3 ) && getMin( y0, y1 ) <= y && y <= getMax( y0, y1 ) )
            return true;
        else
            return false;
    }
    else
    {
        if( b / a == d / c )
        {
            if( y0 - b * x0 / a != y2 - d * x2 / c )
                return false;
            else
            {
                if( getMin( x0, x1 ) <= getMin( x2, x3 ) && getMin( x2, x3 ) <= getMax( x0, x1 ) || getMin( x0, x1 ) <= getMax( x2, x3 ) && getMax( x2, x3 ) <= getMax( x0, x1 ) )
                    return true;
                else if( getMin( x2, x3 ) <= getMin( x0, x1 ) && getMin( x0, x1 ) <= getMax( x2, x3 ) )
                    return true;
                else
                    return false;
            }
        }
        else
        {
            x = - ( y0 - y2 + d * x2 / c - b * x0 / a ) / ( b / a - d / c );
            y = b * x / a + y0 - b * x0 / a;
            if( getMin( x0, x1 ) <= x && x <= getMax( x0, x1 ) && getMin( y2, y3 ) <= y && y <= getMax( y2, y3 ) )
                return true;
            else
                return false;
        }
    }
}


point calcDistance( double x1, double y1, double x2, double y2, double xp, double yp )
{
    point p;
    double a, b, x, y;
    a = x2 - x1;
    b = y2 - y1;

    //直線s1に対して、点pから垂線をおろした時の距離を求める。
    if( a == 0 )
    {
        if( getMin( x1, x2 ) <= xp && xp <= getMax( x1, x2 ) && getMin( y1, y2 ) <= yp && yp <= getMax( y1, y2 ) )
        {
            p.x = xp;
            p.y = yp;
            p.d = 0;
        }
        else if( getMin( x1, x2 ) <= xp && xp <= getMax( x1, x2 ) )
        {
            p.x = -20000;
            p.y = -20000;
            p.d = getMin( twopointsDistance( x1, y1, x1, yp ), twopointsDistance( x2, y2, x1, yp ) );
        }
        else if( getMin( y1, y2 ) <= yp && yp <= getMax( y1, y2 ) )
        {
            p.x = x1;
            p.y = yp;
            p.d = twopointsDistance( x1, yp, xp, yp );
        }
        else
        {
            p.x = -20000;
            p.y = -20000;
            p.d = -1;
        }
    }
    else if( b == 0 )
    {
        //cout << "a" << endl;
        if( getMin( x1, x2 ) <= xp && xp <= getMax( x1, x2 ) && getMin( y1, y2 ) <= yp && yp <= getMax( y1, y2 ) )
        {
            p.x = xp;
            p.y = yp;
            p.d = 0;
        }
        else if( getMin( y1, y2 ) <= yp && yp <= getMax( y1, y2 ) )
        {
            p.x = -20000;
            p.y = -20000;
            p.d = getMin( twopointsDistance( x1, y1, xp, yp ), twopointsDistance( x2, y2, xp, yp ) );
        }
        else if( getMin( x1, x2 ) <= xp && xp <= getMax( x1, x2 ) )
        {
            p.x = xp;
            p.y = y1;
            p.d = twopointsDistance( xp, y1, xp, yp );
        }
        else
        {
            p.x = -20000;
            p.y = -20000;
            p.d = -1;
        }
    }
    else
    {
        x = ( yp - y1 + a * xp / b + b * x1 / a ) / ( b / a + a / b );
        y = -1 * a * x / b + yp + a * xp / b;
        if( getMin( x1, x2 ) <= x && x <= getMax( x1, x2 ) && getMin( y1, y2 ) <= y && y <= getMax( y1, y2 ) )
        {
            p.x = x;
            p.y = y;
            p.d = twopointsDistance( x, y, xp, yp );
        }
        else
        {
            p.x = -20000;
            p.y = -20000;
            p.d = -1;
        }
    }
    return p;
}

int main()
{
    double x0, y0, x1, y1, x2, y2, x3, y3;
    int q;
 
    cin >> q;

    for( int i = 0; i < q; i++ )
    {
        cin >> x0 >> y0 >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;

        if( Intersection( x0, y0, x1, y1, x2, y2, x3, y3 ) == true )
        {
            cout << fixed << setprecision(10) << 0.0000000000 << endl;
            continue;
        }

        point p[8];
        p[0] = calcDistance( x0, y0, x1, y1, x2, y2 );
        p[1] = calcDistance( x0, y0, x1, y1, x3, y3 );
        p[2] = calcDistance( x2, y2, x3, y3, x0, y0 );
        p[3] = calcDistance( x2, y2, x3, y3, x1, y1 );
        p[4].d = twopointsDistance( x0, y0, x2, y2 );
        p[5].d = twopointsDistance( x0, y0, x3, y3 );
        p[6].d = twopointsDistance( x1, y1, x2, y2 );
        p[7].d = twopointsDistance( x1, y1, x3, y3 );

        double min = 100000;
        int j;
        for( int i = 0; i < 8; i++ )
        {
            if( min > p[i].d && p[i].d != -1 )
            {
                min = p[i].d;
                j = i;
            }
            //cout << p[i].x << " " << p[i].y << endl;
            //cout << p[i].d << endl;
        }
        for( int i = 0; i < 8; i++ )
        {
            if( min == p[i].d )
            {
                if( getMin( x0, x1 ) <= p[i].x && p[i].x <= getMax( x0, x1 ) && getMin( y0, y1 ) <= p[i].y && p[i].y <= getMax( y0, y1 ) )
                    if( getMin( x2, x3 ) <= p[i].x && p[i].x <= getMax( x2, x3 ) && getMin( y2, y3 ) <= p[i].y && p[i].y <= getMax( y2, y3 ) )
                        min = 0;
            }
        }
        cout << fixed << setprecision(10) << min << endl;
    }
    return 0;
}


Measured memory_bytes: 3292