7 #define OUTPUT_SIGN(sa,sb,ua,ub)                                        \ 
   11      ua = negA ? -sa : sa;                                                   \ 
   12      ub = negB ? -sb : sb;                                                   \ 
   13      (negA && !negB) || (!negA && negB); }) 
   16 #define MASK_LO ((((int128_t)1)<<64)-1) 
   17 #define MASK_HI (~MASK_LO) 
   20 int64x64_t::Mul (int64x64_t 
const &o)
 
   25   int128_t result = Umul (a, b);
 
   27   result = negResult ? -result : result;
 
   32 int64x64_t::Umul (uint128_t a, uint128_t b)
 
   36   uint128_t aH = (a >> 64) & MASK_LO;
 
   37   uint128_t bH = (b >> 64) & MASK_LO;
 
   40   uint128_t hiPart,loPart,midPart;
 
   48   midPart = aL * bH + aH * bL;
 
   50   result = (loPart >> 64) + (midPart & MASK_LO);
 
   57                    "High precision 128 bits multiplication error: multiplication overflow.");
 
   61 int64x64_t::Div (int64x64_t 
const &o)
 
   66   int128_t result = Divu (a, b);
 
   67   result = negResult ? -result : result;
 
   72 int64x64_t::Divu (uint128_t a, uint128_t b)
 
   74   uint128_t quo = a / b;
 
   75   uint128_t rem = (a % b);
 
   76   uint128_t result = quo << 64;
 
   78   uint128_t tmp = rem >> 64;
 
   90   result = result + quo;
 
   95 int64x64_t::MulByInvert (
const int64x64_t &o)
 
   97   bool negResult = _v < 0;
 
   98   uint128_t a = negResult ? -_v : _v;
 
   99   uint128_t result = UmulByInvert (a, o._v);
 
  101   _v = negResult ? -result : result;
 
  104 int64x64_t::UmulByInvert (uint128_t a, uint128_t b)
 
  106   uint128_t result, ah, bh, al, bl;
 
  113   mid = ah * bl + al * bh;
 
  119 int64x64_t::Invert (uint64_t v)
 
  126   result._v = Divu (a, v);
 
  127   int64x64_t tmp = int64x64_t (v, 
false);
 
  128   tmp.MulByInvert (result);
 
  129   if (tmp.GetHigh () != 1)