예제 #1
0
 // xR mod m
 public BigInteger convert(BigInteger x)
 {
     if (x == null)
     {
         return null;
     }
     BigInteger r = new BigInteger();
     x.abs().dlShiftTo(this.m.t, r);
     r.divRemTo(this.m, null, r);
     if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0)
     {
         this.m.subTo(r, r);
     }
     return r;
 }
예제 #2
0
 // (protected) r = this * a, r != this,a (HAC 14.12)
 // "this" should be the larger one if appropriate.
 public void multiplyTo(BigInteger a, BigInteger r)
 {
     if (a == null)
     {
         return;
     }
     if (r == null)
     {
         r = new BigInteger();
     }
     BigInteger x = this.abs(), y = a.abs();
     int i = x.t;
     r.t = i + y.t;
     while (--i >= 0)
     {
         r.SetData(i, 0);
     }
     for (i = 0; i < y.t; ++i)
     {
         r.datas[i + x.t] = x.am(0, y.datas[i], r.datas, i, 0, x.t);
     }
     r.s = 0;
     r.clamp();
     if (this.s != a.s)
     {
         ZERO.subTo(r, r);
     }
 }
예제 #3
0
        // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
        // r != q, this != m. q or r may be null.
        public void divRemTo(BigInteger m, BigInteger q, BigInteger r)
        {
            if (m == null)
            {
                return;
            }
            if (q == null)
            {
                q = new BigInteger();
            }
            if (r == null)
            {
                r = new BigInteger();
            }

            BigInteger pm = m.abs();
            if (pm.t <= 0)
            {
                return;
            }
            BigInteger pt = this.abs();
            if (pt.t < pm.t)
            {
                if (q != null)
                {
                    q.fromInt(0);
                }
                if (r != null)
                {
                    this.copyTo(r);
                }
                return;
            }

            BigInteger y = new BigInteger();
            int ts = this.s, ms = m.s;
            int nsh = this.DB - nbits(pm.datas[pm.t - 1]); // normalize modulus
            if (nsh > 0)
            {
                pm.lShiftTo(nsh, y);
                pt.lShiftTo(nsh, r);
            }
            else
            {
                pm.copyTo(y);
                pt.copyTo(r);
            }
            int ys = y.t;
            int y0 = y.datas[ys - 1];
            if (y0 == 0)
            {
                return;
            }
            long yt = (long)y0 * (1 << this.F1) + ((ys > 1) ? y.datas[ys - 2] >> this.F2 : 0);
            double d1 = (double)this.FV / yt;
            double d2 = (double)((long)1 << this.F1) / yt;
            int e = 1 << this.F2;
            int i = r.t, j = i - ys;
            BigInteger t = (q == null) ? new BigInteger() : q;
            y.dlShiftTo(j, t);
            if (r.compareTo(t) >= 0)
            {
                r.SetData(r.t++, 1);
                r.subTo(t, r);
            }
            ONE.dlShiftTo(ys, t);
            t.subTo(y, y); // "negative" y so we can replace sub with am later
            while (y.t < ys)
            {
                y.SetData(y.t++, 0);
            }
            while (--j >= 0)
            {
                // Estimate quotient digit
                int qd = (r.datas[--i] == y0) ? this.DM
                    : Convert.ToInt32(Math.Floor((double)r.datas[i] * d1 + (double)(r.datas[i - 1] + e) * d2));
                int tmp = y.am(0, qd, r.datas, j, 0, ys);
                if ((r.datas[i] += tmp) < qd)
                {
                    // Try it out
                    y.dlShiftTo(j, t);
                    r.subTo(t, r);
                    while (r.datas[i] < --qd)
                    {
                        r.subTo(t, r);
                    }
                }
            }
            if (q != null)
            {
                r.drShiftTo(ys, q);
                if (ts != ms)
                {
                    ZERO.subTo(q, q);
                }
            }
            r.t = ys;
            r.clamp();
            if (nsh > 0)
            {
                r.rShiftTo(nsh, r); // Denormalize remainder
            }
            if (ts < 0)
            {
                ZERO.subTo(r, r);
            }
        }