public int CompareTo(object obj)
        {
            Integer x;

            if (obj is Integer)
            {
                x = (Integer)obj;
            }
            else if (obj is long)
            {
                x = new Integer((long)obj);
            }
            else
            {
                return(new Numeric((int)this).CompareTo(obj));
            }
            int n  = bytes.Length;            // code copied from next routine (shift = 0) following profiling
            int xn = x.bytes.Length;
            int j;

            if (bytes.Length == 0)
            {
                if (x.bytes.Length == 0)
                {
                    return(0);
                }
                if (x.bytes[0] <= 127)
                {
                    return(-1);
                }
                return(1);
            }
            else if (bytes[0] > 127)
            {
                if (x.bytes.Length == 0)
                {
                    return(-1);
                }
                if (x.bytes[0] <= 127)
                {
                    return(-1);
                }
                if (n < xn)
                {
                    return(1);
                }
                if (n > xn)
                {
                    return(-1);
                }
                for (j = 0; j < n; j++)
                {
                    byte b = (j < xn)?x.bytes[j]:(byte)0;
                    if (bytes[j] < b)
                    {
                        return(-1);
                    }
                    if (bytes[j] > b)
                    {
                        return(1);
                    }
                }
            }
            else
            {
                if (x.bytes.Length == 0)
                {
                    return(1);
                }
                if (x.bytes[0] > 127)
                {
                    return(1);
                }
                if (n < xn)
                {
                    return(-1);
                }
                if (n > xn)
                {
                    return(1);
                }
                for (j = 0; j < n; j++)
                {
                    byte b = (j < xn)?x.bytes[j]:(byte)0;
                    if (bytes[j] < b)
                    {
                        return(-1);
                    }
                    if (bytes[j] > b)
                    {
                        return(1);
                    }
                }
            }
            return(0);
        }
        internal int CompareTo(Integer x, int shift)
        {
            int n  = bytes.Length;
            int xn = x.bytes.Length;
            int j;

            if (bytes.Length == 0)
            {
                if (x.bytes.Length == 0)
                {
                    return(0);
                }
                if (x.bytes[0] <= 127)
                {
                    return(-1);
                }
                return(1);
            }
            else if (bytes[0] > 127)
            {
                if (x.bytes.Length == 0)
                {
                    return(-1);
                }
                if (x.bytes[0] <= 127)
                {
                    return(-1);
                }
                if (n < xn + shift)
                {
                    return(1);
                }
                if (n > xn + shift)
                {
                    return(-1);
                }
                for (j = 0; j < n; j++)
                {
                    byte b = (j < xn)?x.bytes[j]:(byte)0;
                    if (bytes[j] < b)
                    {
                        return(1);
                    }
                    if (bytes[j] > b)
                    {
                        return(-1);
                    }
                }
            }
            else
            {
                if (x.bytes.Length == 0)
                {
                    return(1);
                }
                if (x.bytes[0] > 127)
                {
                    return(1);
                }
                if (n < xn + shift)
                {
                    return(-1);
                }
                if (n > xn + shift)
                {
                    return(1);
                }
                for (j = 0; j < n; j++)
                {
                    byte b = (j < xn)?x.bytes[j]:(byte)0;
                    if (bytes[j] < b)
                    {
                        return(-1);
                    }
                    if (bytes[j] > b)
                    {
                        return(1);
                    }
                }
            }
            return(0);
        }
        public static Integer operator /(Integer a, Integer b)
        {
            bool sa = a.Sign;
            bool sb = b.Sign;
            bool s  = (sa != sb);

            if (sa)
            {
                a = a.Negate();
            }
            if (sb)
            {
                b = b.Negate();
            }
            if (b.IsZero() || a < b)
            {
                return(Zero);
            }
            if (b == a)
            {
                return(One);
            }
            var ds = new List <Integer>();

            for (; ;)
            {
                ds.Add(b);
                Integer c = b.Shift8();
                if (c > a)
                {
                    break;
                }
                b = c;
            }
            int d = 0;

            // first work out the most significant digit
            while (b <= a)
            {
                a = a - b; // b is ds[ds.Count-1]
                d++;
            }
            // fix the sign
            int j  = (d > 127) ? 1 : 0;
            var nb = new byte[ds.Count + j];

            nb[j++] = (byte)d;
            // now do the rest of the digits
            for (int i = ds.Count - 2; i >= 0; i--)
            {
                var dv = ds[i];
                d = 0;
                while (dv <= a)
                {
                    a = a - dv;
                    d++;
                }
                nb[j++] = (byte)d;
            }
            var r = new Integer(nb);

            if (s)
            {
                r = r.Negate();
            }
            return(r);
        }
        internal Integer Add(Integer b, int shift)
        {
            int  off = 0, boff = 0, m;
            int  h = 0;
            int  n = bytes.Length, bn = b.bytes.Length + shift;
            bool s = Sign, bs = b.Sign;

            if (n > bn)
            {
                boff = n - bn;
                m    = n;
            }
            else
            {
                off = bn - n;
                m   = bn;
            }
            byte[] t = new byte[m + 1];
            int    j;
            uint   r = 0;

            for (j = m - 1; j >= -1; j--)
            {
                uint d = r;
                if (j - off >= 0)
                {
                    d += (uint)bytes[j - off];
                }
                else if (s)
                {
                    d += 255;
                }
                if (j - boff >= b.bytes.Length)
                {
                    d += 0;
                }
                else if (j - boff >= 0)
                {
                    d += (uint)b.bytes[j - boff];
                }
                else if (bs)
                {
                    d += 255;
                }
                t[j + 1] = (byte)(d & 0xff);
                r        = d >> 8;
            }
            if (t[0] == 255)
            {
                h = 255;
            }
            j = 0;
            while (j < m + 1 && t[j] == h)
            {
                j++;
            }
            if (j == m + 1 || (h == 255 && t[j] <= 127) || (h == 0 && t[j] > 127))
            {
                j--;
            }
            byte[] c = new byte[m + 1 - j];
            for (int k = 0; k < c.Length; k++)
            {
                c[k] = t[j + k];
            }
            return(new Integer(c));
        }
 internal Numeric(long n)
 {
     mantissa = new Integer(n);
     scale    = 0;
 }
 public Numeric(long m, int s, int p = 0)
 {
     mantissa  = new Integer(m);
     scale     = s;
     precision = p;
 }
 public Numeric(Integer m, int s, int p = 0)
 {
     mantissa  = m;
     scale     = s;
     precision = p;
 }