#include "stdio.h"
#include <cmath>

double dot(double * u, double * v);
double abs(double * u);
double min(double a, double b, double c, double d);
void prod(double k, double * u, double * v);
void diff(double * a, double * b, double * c);
void summ(double * a, double * b, double * c);
bool in(double s);
bool in(double s, double t);
double sd(double s, double t);
double _(double s);

double P0[4],P1[4],Q0[4],Q1[4];
double u[4],v[4],w0[4];

double InterSegmentDistance4d()
//input: four 4d points P0, P1, Q0, Q1
// output: r = minimal distance between lines segments P0P1 and Q0Q1
    {
      double r = 0;
      //calculation of three vectors
	  //u = P1 - P0, v = Q1 - Q0, w0 = Q0 - P0
          diff(P1, P0, u);  diff(Q1, Q0, v);  diff(Q0, P0, w0);
	   //calculation of supporting scalar variables
	    //a = u*u, b = u*v, c = v*v, d = w0*u, e = w0*v
	    double  a, b, c, d, e;
    	        a = dot(u,u);  // a=u^2;
	            b = dot(u,v);
	            c = dot(v,v);  // c=v^2;
	            d = dot(u,w0);
	            e = dot(v,w0);
	 //calculation of main determinant
	     // D = b^2 - a*c
	      double D = b*b - a*c;
	      if (D == 0) //lines are parallel
            {
             double t0=-e/c; double t1=-e/c; double s0 = (-e+b)/c ; double s1= (e-c)*b/(c*a);
            if (in(t0) || in(t1) || in(s0) || in(s1))
               {
                   double wq[4];
                  prod(e/c,v,  wq);  //projection w0 on line q
                  double wd[4];
                   diff(w0,wq,  wd);
                    r = abs(wd);
                     return r ; //r = |w0 - wq|
                }
               //else minimal distance between segments equals minimal distance between ends of segments
                     r = min(sd(0,0), sd(0,1), sd(1,0), sd(1,1));
		             return r;
            }
	       // else lines are not parallel
	        {
                //calculation of determinants
		    double D1 = b*e - c*d,  D2 = a*e - b*d;
		    //calculation of parameters for minimal segment between lines
            double sc = D1/D, tc = D2/D;
             if(in(sc,tc)) //minimal distance between segments equals minimal distance between lines
                {
                   return r = sd(sc,tc); // r = |wc|
                }
             //else minimal segment is defined by some parameter point (s,t) on edge of square [0,1]x[0,1]
                 {
                    double t1 = 0,   s1=_(d/a);
                    double t2 = _(-2*e/c), s2=0;
                    double t3 = 1,   s3=_(2*(b+d)/a);
                    double t4 = _(2*(b+e)/c), s4=0;
                    return min(sd(s1,t1), sd(s2,t2),sd(s3,t3), sd(s4,t4));
                 }
	        }
    }

int main()
{
	scanf("%lf %lf %lf %lf",&P0[0], &P0[1], &P0[2],&P0[3]);
	scanf("%lf %lf %lf %lf",&P1[0], &P1[1], &P1[2],&P1[3]);
scanf("%lf %lf %lf %lf",&Q0[0], &Q0[1], &Q0[2],&Q0[3]);
	scanf("%lf %lf %lf %lf",&Q1[0], &Q1[1], &Q1[2],&Q1[3]);
        printf("%lf\n", InterSegmentDistance4d());
        return 0;
}

double dot(double * u, double * v)//calculing the scalar production of two vectors
{
    return u[0]*v[0]+u[1]*v[1]+u[2]*v[2]+u[3]*v[3];
}

double abs(double * u)//finding the length of vector
{
    return sqrt(dot(u,u));
}

double min(double a, double b, double c, double d)//finding the minimal value
{
    double m = a;
     if(m>b) m = b;
      if(m>c) m = c;
       if(m>d) m = d;
        return m;
}

void diff(double * a, double * b, double * c)//finding the difference of two 4d objects(dots or vectors)
{
	c[0]=a[0]-b[0];
	c[1]=a[1]-b[1];
	c[2]=a[2]-b[2];
	c[3]=a[3]-b[3];
}

void summ(double * a, double * b, double * c)//finding the sum of two 4d objects(dots or vecrors)
{
	c[0]=a[0]+b[0];
	c[1]=a[1]+b[1];
	c[2]=a[2]+b[2];
	c[3]=a[3]+b[3];
}

void prod(double k, double * u, double * v)//calculing the production of vector and number
{
 v[0] = k * u[0];
 v[1] = k * u[1];
 v[2] = k * u[2];
 v[3] = k * u[3];
}

bool in(double s)//checking if the vatue is between 0 and 1
 {
    return 0 <= s && s <= 1 ;
 }

bool in(double s, double t)//variation of the previous function for two values
{
    return  in(t) && in(s);
}

double sd(double s, double t)//finding the distance between two segments using two parameters s and t
{
    double Pc[4], Qc[4], W[4];
     prod(s,u, Pc);
      summ(Pc,P0, Pc);
     prod(t,v, Qc);
      summ(Qc,Q0, Qc);
       diff(Qc, Pc, W);
        return  abs(W);
}

double _(double s)//restriction the value for the interval [0,1]
{
   double s1 = s;
   if(s > 1)s1 = 1;
   if(s < 0)s1 = 0;
    return s1;
}