14 #define OUTPUT_SIGN(sa,sb,ua,ub) \
18 ua = negA ? -sa : sa; \
19 ub = negB ? -sb : sb; \
20 (negA && !negB) || (!negA && negB); })
23 #define MASK_LO ((((int128_t)1)<<64)-1)
24 #define MASK_HI (~MASK_LO)
27 int64x64_t::Mul (int64x64_t
const &o)
32 int128_t result = Umul (a, b);
34 result = negResult ? -result : result;
39 int64x64_t::Umul (uint128_t a, uint128_t b)
43 uint128_t aH = (a >> 64) & MASK_LO;
44 uint128_t bH = (b >> 64) & MASK_LO;
47 uint128_t hiPart,loPart,midPart;
55 midPart = aL * bH + aH * bL;
57 result = (loPart >> 64) + (midPart & MASK_LO);
64 "High precision 128 bits multiplication error: multiplication overflow.");
68 int64x64_t::Div (int64x64_t
const &o)
73 int128_t result = Divu (a, b);
74 result = negResult ? -result : result;
79 int64x64_t::Divu (uint128_t a, uint128_t b)
81 uint128_t quo = a / b;
82 uint128_t rem = (a % b);
83 uint128_t result = quo << 64;
85 uint128_t tmp = rem >> 64;
97 result = result + quo;
102 int64x64_t::MulByInvert (
const int64x64_t &o)
104 bool negResult = _v < 0;
105 uint128_t a = negResult ? -_v : _v;
106 uint128_t result = UmulByInvert (a, o._v);
108 _v = negResult ? -result : result;
111 int64x64_t::UmulByInvert (uint128_t a, uint128_t b)
113 uint128_t result, ah, bh, al, bl;
120 mid = ah * bl + al * bh;
126 int64x64_t::Invert (uint64_t v)
133 result._v = Divu (a, v);
134 int64x64_t tmp = int64x64_t (v,
false);
135 tmp.MulByInvert (result);
136 if (tmp.GetHigh () != 1)
#define OUTPUT_SIGN(sa, sb, ua, ub)
#define NS_ASSERT(condition)
NS_LOG_COMPONENT_DEFINE("int64x64-128")
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.