typedef struct /* Definitely a better way to do all this of this nonsense */
{
  REAL x0;
  REAL x1;
} RealTuple2;

typedef struct
{
  REAL x0;
  REAL x1;
  REAL x2;
} RealTuple3;

typedef struct
{
  REAL x0;
  REAL x1;
  REAL x2;
  REAL x3;
} RealTuple4;

typedef struct
{
  REAL x0;
  REAL x1;
  REAL x2;
  REAL x3;
  REAL x4;
} RealTuple5;

typedef struct
{
  REAL x0;
  REAL x1;
  REAL x2;
  REAL x3;
  REAL x4;
  REAL x5;
} RealTuple6;

typedef struct
{
  REAL x0;
  REAL x1;
  REAL x2;
  REAL x3;
  REAL x4;
  REAL x5;
  REAL x6;
} RealTuple7;

typedef struct
{
  REAL x0;
  REAL x1;
  REAL x2;
  REAL x3;
  REAL x4;
  REAL x5;
  REAL x6;
  REAL x7;
} RealTuple8;

typedef struct
{
  REAL x0;
  REAL x1;
  REAL x2;
  REAL x3;
  REAL x4;
  REAL x5;
  REAL x6;
  REAL x7;
  REAL x8;
} RealTuple9;

typedef struct
{
  REAL x0;
  REAL x1;
  REAL x2;
  REAL x3;
  REAL x4;
  REAL x5;
  REAL x6;
  REAL x7;
  REAL x8;
  REAL x9;
} RealTuple10;

typedef struct
{
  REAL x0;
  REAL x1;
  REAL x2;
  REAL x3;
  REAL x4;
  REAL x5;
  REAL x6;
  REAL x7;
  REAL x8;
  REAL x9;
  REAL x10;
} RealTuple11;

typedef struct
{
  REAL x0;
  REAL x1;
  REAL x2;
  REAL x3;
  REAL x4;
  REAL x5;
  REAL x6;
  REAL x7;
  REAL x8;
  REAL x9;
  REAL x10;
  REAL x11;
} RealTuple12;

REAL _Absolute(REAL a)
{
  return Absolute(a);
}

REAL _Fast_Two_Sum_Tail(REAL a, REAL b, REAL x)
{
  REAL bvirt, y;
  Fast_Two_Sum_Tail(a, b, x, y);
  return y;
}

RealTuple2 _Fast_Two_Sum(REAL a, REAL b)
{
  REAL x, y;
  REAL bvirt;
  Fast_Two_Sum(a, b, x, y);
  RealTuple2 result = {x, y};
  return result;
};

REAL _Fast_Two_Diff_Tail(REAL a, REAL b, REAL x)
{
  REAL bvirt, y;
  Fast_Two_Diff_Tail(a, b, x, y);
  return y;
}

RealTuple2 _Fast_Two_Diff(REAL a, REAL b)
{
  REAL x, y, bvirt;
  Fast_Two_Diff(a, b, x, y);
  RealTuple2 result = {x, y};
  return result;
}

REAL _Two_Sum_Tail(REAL a, REAL b, REAL x)
{
  REAL avirt, bvirt, around, bround, y;
  Two_Sum_Tail(a, b, x, y);
  return y;
}

RealTuple2 _Two_Sum(REAL a, REAL b)
{
  REAL x, y, avirt, bvirt, around, bround;
  Two_Sum(a, b, x, y);
  RealTuple2 result = {x, y};
  return result;
}

REAL _Two_Diff_Tail(REAL a, REAL b, REAL x)
{
  REAL avirt, bvirt, around, bround, y;
  Two_Diff_Tail(a, b, x, y);
  return y;
}

RealTuple2 _Two_Diff(REAL a, REAL b)
{
  REAL x, y;
  REAL avirt, bvirt, around, bround;
  Two_Diff(a, b, x, y);
  RealTuple2 result = {x, y};
  return result;
}

RealTuple2 _Split(REAL a)
{
  REAL c, abig, ahi, alo;
  Split(a, ahi, alo);
  RealTuple2 result = {ahi, alo};
  return result;
}

REAL _Two_Product_Tail(REAL a, REAL b, REAL x)
{
  REAL ahi, alo, bhi, blo, y, c, abig, err1, err2, err3;
  Two_Product_Tail(a, b, x, y);
  return y;
}

RealTuple2 _Two_Product(REAL a, REAL b)
{
  REAL x, y, ahi, alo, bhi, blo, abig, err1, err2, err3, c;
  Two_Product(a, b, x, y);
  RealTuple2 result = {x, y};
  return result;
}

RealTuple2 _Two_Product_Presplit(REAL a, REAL b, REAL bhi, REAL blo)
{
  REAL x, y, ahi, alo, err1, err2, err3, c, abig;
  Two_Product_Presplit(a, b, bhi, blo, x, y);
  RealTuple2 result = {x, y};
  return result;
}

RealTuple2 _Two_Product_2Presplit(REAL a, REAL ahi, REAL alo, REAL b, REAL bhi, REAL blo)
{
  REAL x, y, err1, err2, err3;
  Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y);
  RealTuple2 result = {x, y};
  return result;
}

REAL _Square_Tail(REAL a, REAL x)
{
  REAL ahi, alo, y, abig, err1, err3, c;
  Square_Tail(a, x, y);
  return y;
}

RealTuple2 _Square(REAL a)
{
  REAL x, y, c, abig, err1, err3, ahi, alo;
  Square(a, x, y);
  RealTuple2 result = {x, y};
  return result;
}

RealTuple3 _Two_One_Sum(REAL a1, REAL a0, REAL b)
{
  REAL x2, x1, x0, _i, bvirt, avirt, bround, around;
  Two_One_Sum(a1, a0, b, x2, x1, x0);
  RealTuple3 result = {x2, x1, x0};
  return result;
}

RealTuple3 _Two_One_Diff(REAL a1, REAL a0, REAL b)
{
  REAL x2, x1, x0, _i, avirt, bvirt, around, bround;
  Two_One_Diff(a1, a0, b, x2, x1, x0);
  RealTuple3 result = {x2, x1, x0};
  return result;
}

RealTuple4 _Two_Two_Sum(REAL a1, REAL a0, REAL b1, REAL b0)
{
  REAL x3, x2, x1, x0, _i, avirt, bvirt, around, bround, _j, _0;
  Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0);
  RealTuple4 result = {x3, x2, x1, x0};
  return result;
}

RealTuple4 _Two_Two_Diff(REAL a1, REAL a0, REAL b1, REAL b0)
{
  REAL x3, x2, x1, x0, _i, avirt, bvirt, around, bround, _j, _0;
  Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0);
  RealTuple4 result = {x3, x2, x1, x0};
  return result;
}

RealTuple5 _Four_One_Sum(REAL a3, REAL a2, REAL a1, REAL a0, REAL b)
{
  REAL x4, x3, x2, x1, x0, _i, avirt, bvirt, around, bround, _j, _0;
  Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0);
  RealTuple5 result = {x4, x3, x2, x1, x0};
  return result;
}


RealTuple6 _Four_Two_Sum(REAL a3, REAL a2, REAL a1, REAL a0, REAL b1, REAL b0)
{
  REAL x5, x4, x3, x2, x1, x0, _i, _j, _k, avirt, bvirt, around, bround, _0, _1, _2;
  Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0);
  RealTuple6 result = {x5, x4, x3, x2, x1, x0};
  return result;
}


RealTuple8 _Four_Four_Sum(REAL a3, REAL a2, REAL a1, REAL a0, REAL b4, REAL b3, REAL b1, REAL b0)
{
  REAL x7, x6, x5, x4, x3, x2, x1, x0, _i, _j, _k, _l, _0, _1, _2, avirt, bvirt, around, bround;
  Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0);
  RealTuple8 result = {x7, x6, x5, x4, x3, x2, x1, x0};
  return result;
}

RealTuple9 _Eight_One_Sum(REAL a7, REAL a6, REAL a5, REAL a4, REAL a3, REAL a2, REAL a1, REAL a0, REAL b)
{
  REAL x8, x7, x6, x5, x4, x3, x2, x1, x0, _i, _j, avirt, bvirt, around, bround;
  Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, x3, x2, x1, x0);
  RealTuple9 result = {x8, x7, x6, x5, x4, x3, x2, x1, x0};
  return result;
}

RealTuple10 _Eight_Two_Sum(REAL a7, REAL a6, REAL a5, REAL a4, REAL a3, REAL a2, REAL a1, REAL a0, REAL b1, REAL b0)
{
  REAL x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, _i, _j, _k, _0, _1, _2, _3, _4, _5, _6, avirt, bvirt, around, bround;
  Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0);
  RealTuple10 result = {x9, x8, x7, x6, x5, x4, x3, x2, x1, x0};
  return result;
}


RealTuple12 _Eight_Four_Sum(REAL a7, REAL a6, REAL a5, REAL a4, REAL a3, REAL a2, REAL a1, REAL a0, REAL b4, REAL b3, REAL b1, REAL b0)
{
  REAL x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, _0, _1, _2, _3, _4, _5, _6, _i, _j, _k, _l, avirt, bvirt, around, bround;
  Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0);
  RealTuple12 result = {x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0};
  return result;
}

RealTuple4 _Two_One_Product(REAL a1, REAL a0, REAL b)
{
  REAL x3, x2, x1, x0, _i, _j, _k, _0, c, abig, bhi, blo, ahi, alo, err1, err2, err3, avirt, bvirt, around, bround;
  Two_One_Product(a1, a0, b, x3, x2, x1, x0);
  RealTuple4 result = {x3, x2, x1, x0};
  return result;
}

RealTuple8 _Four_One_Product(REAL a3, REAL a2, REAL a1, REAL a0, REAL b)
{
  REAL x7, x6, x5, x4, x3, x2, x1, x0, avirt, bvirt, around, bround, _i, _j, _k, _0, ahi, alo, bhi, blo, err1, err2, err3, c, abig;
  Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0);
  RealTuple8 result = {x7, x6, x5, x4, x3, x2, x1, x0};
  return result;
}


RealTuple8 _Two_Two_Product(REAL a1, REAL a0, REAL b1, REAL b0)
{
  REAL x7, x6, x5, x4, x3, x2, x1, x0, a0hi, abig, a0lo, bhi, blo, _i, _j, _k, _l, _m, _0, _1, _2, c, err1, err2, err3, a1hi, a1lo, bvirt, avirt, bround, around, _n;
  Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0);
  RealTuple8 result = {x7, x6, x5, x4, x3, x2, x1, x0};
  return result;
}

#define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \
  Square(a0, _1, x0);                              \
  _2 = a0 + a0;                                    \
  Two_Product(a1, _2, _3, _4);                     \
  Two_One_Sum(_3, _4, _1, _5, _6, x1);             \
  Square(a1, _7, _8);                              \
  Two_Two_Sum(_7, _8, _5, _6, x5, x4, x3, x2);

RealTuple6 _Two_Square(REAL a1, REAL a0)
{
  REAL x5, x4, x3, x2, x1, x0, _i, _j, _0, _1, _2, _3, _4, _5, _6, _7, _8, c, abig, ahi, alo, err1, err2, err3, avirt, bvirt, around, bround, _k, bhi, blo, _l;
  Two_Square(a1, a0, x5, x4, x3, x2, x1, x0);
  RealTuple6 result = {x5, x4, x3, x2, x1, x0};
  return result;
}

typedef struct
{
  REAL epsilon;
  REAL splitter;
  REAL resulterrbound;
  REAL ccwerrboundA;
  REAL ccwerrboundB;
  REAL ccwerrboundC;
  REAL o3derrboundA;
  REAL o3derrboundB;
  REAL o3derrboundC;
  REAL iccerrboundA;
  REAL iccerrboundB;
  REAL iccerrboundC;
  REAL isperrboundA;
  REAL isperrboundB;
  REAL isperrboundC;
} InitResults;

InitResults exactinit2()
{
  REAL half;
  REAL check, lastcheck;
  int every_other;

  every_other = 1;
  half = 0.5;
  epsilon = 1.0;
  splitter = 1.0;
  check = 1.0;
  /* Repeatedly divide `epsilon' by two until it is too small to add to    */
  /*   one without causing roundoff.  (Also check if the sum is equal to   */
  /*   the previous sum, for machines that round up instead of using exact */
  /*   rounding.  Not that this library will work on such machines anyway. */
  do
  {
    lastcheck = check;
    epsilon *= half;
    if (every_other)
    {
      splitter *= 2.0;
    }
    every_other = !every_other;
    check = 1.0 + epsilon;
  } while ((check != 1.0) && (check != lastcheck));
  splitter += 1.0;

  /* Error bounds for orientation and incircle tests. */
  resulterrbound = (3.0 + 8.0 * epsilon) * epsilon;
  ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon;
  ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon;
  ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon;
  o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon;
  o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon;
  o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon;
  iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon;
  iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon;
  iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon;
  isperrboundA = (16.0 + 224.0 * epsilon) * epsilon;
  isperrboundB = (5.0 + 72.0 * epsilon) * epsilon;
  isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon;
  InitResults result = {epsilon, splitter, resulterrbound, ccwerrboundA, ccwerrboundB, ccwerrboundC,
                        o3derrboundA, o3derrboundB, o3derrboundC, iccerrboundA,
                        iccerrboundB, iccerrboundC, isperrboundA, isperrboundB, isperrboundC};
  return result;
}