Esempio n. 1
0
 public Int128(Int128 val)
 {
     hi = val.hi;
     lo = val.lo;
 }
Esempio n. 2
0
        //------------------------------------------------------------------------------

        double Area(OutRec outRec, bool UseFull64BitRange)
        {
          OutPt op = outRec.pts;
          if (UseFull64BitRange) 
          {
            Int128 a = new Int128(0);
            do
            {
                a += Int128.Int128Mul(op.prev.pt.X, op.pt.Y) -
                    Int128.Int128Mul(op.pt.X, op.prev.pt.Y);
                op = op.next;
            } while (op != outRec.pts);
            return a.ToDouble() / 2;          
          }
          else
          {
            double a = 0;
            do {
              a += (op.prev.pt.X * op.pt.Y) - (op.pt.X * op.prev.pt.Y);
              op = op.next;
            } while (op != outRec.pts);
            return a/2;
          }
        }
Esempio n. 3
0
        //------------------------------------------------------------------------------

        public static double Area(Polygon poly)
        {
            int highI = poly.Count - 1;
            if (highI < 2) return 0;
            if (FullRangeNeeded(poly))
            {
                Int128 a = new Int128();
                a = Int128.Int128Mul(poly[highI].X, poly[0].Y) -
                    Int128.Int128Mul(poly[0].X, poly[highI].Y);
                for (int i = 0; i < highI; ++i)
                    a += Int128.Int128Mul(poly[i].X, poly[i + 1].Y) -
                    Int128.Int128Mul(poly[i + 1].X, poly[i].Y);
                return a.ToDouble() / 2;
            }
            else
            {
                double area = (double)poly[highI].X * (double)poly[0].Y -
                    (double)poly[0].X * (double)poly[highI].Y;
                for (int i = 0; i < highI; ++i)
                    area += (double)poly[i].X * (double)poly[i + 1].Y -
                        (double)poly[i + 1].X * (double)poly[i].Y;
                return area / 2;
            }
        }
Esempio n. 4
0
 public double ToDouble()
 {
     const double shift64 = 18446744073709551616.0; //2^64
     const double bit64 = 9223372036854775808.0; 
     if (hi < 0)
     {
         Int128 tmp = new Int128(this);
         tmp = -tmp;
         if (tmp.lo < 0)
             return (double)tmp.lo - bit64 - tmp.hi * shift64;
         else
             return -(double)tmp.lo - tmp.hi * shift64;
     }
     else if (lo < 0)
         return -(double)lo + bit64 + hi * shift64;
     else
         return (double)lo + (double)hi * shift64;
 }
Esempio n. 5
0
        public static Int128 operator /(Int128 lhs, Int128 rhs)
        {
            if (rhs.lo == 0 && rhs.hi == 0)
                throw new ClipperException("Int128: divide by zero");
            bool negate = (rhs.hi < 0) != (lhs.hi < 0);
            Int128 result = new Int128(lhs), denom = new Int128(rhs);
            if (result.hi < 0) result = -result;
            if (denom.hi < 0) denom = -denom;
            if (denom > result) return new Int128(0); //result is only a fraction of 1
            denom = -denom;

            Int128 p = new Int128(0);
            for (int i = 0; i < 128; ++i)
            {
                p.hi = p.hi << 1;
                if (p.lo < 0) p.hi++;
                p.lo = (Int64)p.lo << 1;
                if (result.hi < 0) p.lo++;
                result.hi = result.hi << 1;
                if (result.lo < 0) result.hi++;
                result.lo = (Int64)result.lo << 1;
                if (p.hi >= 0)
                {
                    p += denom;
                    result.lo++;
                }
            }
            return negate ? -result : result;
        }
Esempio n. 6
0
        //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 Int128 Int128Mul(Int64 lhs, Int64 rhs)
        {
            bool negate = (lhs < 0) != (rhs < 0);
            if (lhs < 0) lhs = -lhs;
            if (rhs < 0) rhs = -rhs;
            UInt64 int1Hi = (UInt64)lhs >> 32;
            UInt64 int1Lo = (UInt64)lhs & 0xFFFFFFFF;
            UInt64 int2Hi = (UInt64)rhs >> 32;
            UInt64 int2Lo = (UInt64)rhs & 0xFFFFFFFF;

            //nb: see comments in clipper.pas
            UInt64 a = int1Hi * int2Hi;
            UInt64 b = int1Lo * int2Lo;
            UInt64 c = int1Hi * int2Lo + int1Lo * int2Hi; 

            Int64 lo, hi;
            hi = (Int64)(a + (c >> 32));

            lo = (Int64)(c << 32);
            lo += (Int64)b;
            if ((UInt64)lo < b) hi++;
            var result = new Int128(lo, hi);
            return negate ? -result : result;            
        }