#include <cstdio>
#include <utility>
#include <vector>
#include <complex>
#include <cmath>

using namespace std;

static const double EPS=1e-12;
static const double INF=1e24;

using Point=complex<double>;
using Plane=vector<Point>;

bool operator<(const Point &a, const Point &b) {
    return real(a)!=real(b)? real(a)<real(b) : imag(a)<imag(b);
}

double cross_prod(const Point &a, const Point &b) {
    return imag(conj(a)*b);
}

double dot_prod(const Point &a, const Point &b) {
    return real(conj(a)*b);
}

enum {
    ONLINE_FRONT=-2,
    CLOCKWISE,
    ON_SEGMENT,
    COUNTER_CLOCKWISE,
    ONLINE_BACK,
};

int ccwise(const Point &a, Point b, Point c) {
    b -= a; c -= a;

    if (cross_prod(b, c) > 0) {
        return COUNTER_CLOCKWISE;
    } else if (cross_prod(b, c) < 0) {
        return CLOCKWISE;
    } else if (dot_prod(b, c) < 0) {
        return ONLINE_BACK;
    } else if (norm(b) < norm(c)) {
        return ONLINE_FRONT;
    } else {
        return ON_SEGMENT;
    }
}

struct Line: public pair<Point, Point> {
    Line() {}
    Line(const Point &a, const Point &b) {
        first = a;
        second = b;
    }
    int _ccwise(const Point &rhs) const {
        return ccwise(first, second, rhs);
    }
    bool intersects(const Line &rhs) const {
        if (abs(cross_prod(second-first, rhs.second-rhs.first)) > EPS)
            // non parallel
            return true;

        // same line
        return abs(cross_prod(second-first, rhs.first-first)) < EPS;
    }
    bool intersects(const Point &rhs) const {
        return abs(cross_prod(second-rhs, first-rhs)) < EPS;
    }
};

struct LineSeg: public pair<Point, Point> {
    LineSeg() {}
    LineSeg(const Point &a, const Point &b) {
        first = a;
        second = b;
    }
    int _ccwise(const Point &rhs) const {
        return ccwise(first, second, rhs);
    }
    bool intersects(const Line &rhs) {
        return (
            cross_prod(rhs.second-rhs.first, first-rhs.first) *
            cross_prod(rhs.second-rhs.first, second-rhs.first)
        ) < EPS;
    }
    bool intersects(const LineSeg &rhs) const {
        if (_ccwise(rhs.first) * _ccwise(rhs.second) > 0)
            return false;

        return rhs._ccwise(first) * rhs._ccwise(second) <= 0;
    }
    bool intersects(const Point &rhs) const {
        return abs(first-rhs)+abs(second-rhs)-abs(second-first) < EPS;
    }
};

double get_distance(const LineSeg &l, const Point &p) {
    if (dot_prod(l.second-l.first, p-l.first) < -EPS) {
        return abs(p-l.first);
    } else if (dot_prod(l.first-l.second, p-l.second) < -EPS) {
        return abs(p-l.second);
    }

    return abs(cross_prod(l.second-l.first, p-l.first))/abs(l.second-l.first);
}

double get_distance(const LineSeg &l, const LineSeg &m) {
    if (l.intersects(m))
        return 0.0;

    return min(
        min(get_distance(l, m.first), get_distance(l, m.second)),
        min(get_distance(m, l.first), get_distance(m, l.second))
    );
}

int main() {
    size_t q;
    scanf("%zu", &q);
    for (size_t i=0; i<q; ++i) {
        double x, y;
        scanf("%lf %lf", &x, &y);
        Point p0(x, y);

        scanf("%lf %lf", &x, &y);
        Point p1(x, y);

        scanf("%lf %lf", &x, &y);
        Point p2(x, y);

        scanf("%lf %lf", &x, &y);
        Point p3(x, y);

        LineSeg l(p0, p1), m(p2, p3);
        printf("%.9f\n", get_distance(l, m));
    }

    return 0;
}

Measured memory_bytes: 2804