//nb: Constructing two new Int128 objects every time we want to multiply longs //is slow. So, although calling the Int128Mul method doesn't look as clean, the //code runs significantly faster than if we'd used the * operator. public static ClipperInt128 Int128Mul(long lhs, long rhs) { bool negate = (lhs < 0) != (rhs < 0); if (lhs < 0) { lhs = -lhs; } if (rhs < 0) { rhs = -rhs; } ulong int1Hi = (ulong)lhs >> 32; ulong int1Lo = (ulong)lhs & 0xFFFFFFFF; ulong int2Hi = (ulong)rhs >> 32; ulong int2Lo = (ulong)rhs & 0xFFFFFFFF; //nb: see comments in clipper.pas ulong a = int1Hi * int2Hi; ulong b = int1Lo * int2Lo; ulong c = int1Hi * int2Lo + int1Lo * int2Hi; ulong lo; long hi; hi = (long)(a + (c >> 32)); unchecked { lo = (c << 32) + b; } if (lo < b) { hi++; } ClipperInt128 result = new ClipperInt128(hi, lo); return(negate ? -result : result); }
public ClipperInt128(ClipperInt128 val) { hi = val.hi; lo = val.lo; }