Exemplo n.º 1
0
 public void ModDiv(ref BigIntegerBuilder regDen, ref BigIntegerBuilder regQuo)
 {
     if (regDen._iuLast == 0)
     {
         regQuo.Set(DivMod(regDen._uSmall));
         Py.Core.Util.Swap <BigIntegerBuilder>(ref this, ref regQuo);
     }
     else if (_iuLast != 0)
     {
         ModDivCore(ref this, ref regDen, true, ref regQuo);
     }
 }
Exemplo n.º 2
0
 public void Mod(ref BigIntegerBuilder regDen)
 {
     if (regDen._iuLast == 0)
     {
         Set(Mod(ref this, regDen._uSmall));
     }
     else if (_iuLast != 0)
     {
         BigIntegerBuilder regQuo = new BigIntegerBuilder();
         ModDivCore(ref this, ref regDen, false, ref regQuo);
     }
 }
Exemplo n.º 3
0
        public void Mul(ref BigIntegerBuilder regMul)
        {
            if (regMul._iuLast == 0)
            {
                Mul(regMul._uSmall);
            }
            else if (_iuLast != 0)
            {
                int num2 = _iuLast + 1;
                SetSizeKeep(num2 + regMul._iuLast, 1);
                int index = num2;
                while (--index >= 0)
                {
                    uint num4 = _rgu[index];
                    _rgu[index] = 0;
                    uint uCarry = 0;
                    for (int i = 0; i <= regMul._iuLast; i++)
                    {
                        uCarry = AddMulCarry(ref _rgu[index + i], regMul._rgu[i], num4, uCarry);
                    }
                    if (uCarry != 0)
                    {
                        for (int j = (index + regMul._iuLast) + 1; (uCarry != 0) && (j <= _iuLast); j++)
                        {
                            uCarry = AddCarry(ref _rgu[j], 0, uCarry);
                        }
                        if (uCarry != 0)
                        {
                            SetSizeKeep(_iuLast + 2, 0);
                            _rgu[_iuLast] = uCarry;
                        }
                    }
                }
            }
            else
            {
                uint u = _uSmall;
                switch (u)
                {
                case 0:
                    break;

                case 1:
                    this = new BigIntegerBuilder(ref regMul);
                    break;

                default:
                    Load(ref regMul, 1);
                    Mul(u);
                    return;
                }
            }
        }
Exemplo n.º 4
0
 public BigIntegerBuilder(ref BigIntegerBuilder reg)
 {
     this = reg;
     if (_fWritable)
     {
         _fWritable = false;
         if (_iuLast == 0)
         {
             _rgu = null;
         }
         else
         {
             reg._fWritable = false;
         }
     }
 }
Exemplo n.º 5
0
 public void Div(ref BigIntegerBuilder regDen)
 {
     if (regDen._iuLast == 0)
     {
         DivMod(regDen._uSmall);
     }
     else if (_iuLast == 0)
     {
         _uSmall = 0;
     }
     else
     {
         BigIntegerBuilder regQuo = new BigIntegerBuilder();
         ModDivCore(ref this, ref regDen, true, ref regQuo);
         Py.Core.Util.Swap <BigIntegerBuilder>(ref this, ref regQuo);
     }
 }
Exemplo n.º 6
0
        public static uint Mod(ref BigIntegerBuilder regNum, uint uDen)
        {
            if (uDen == 1)
            {
                return(0);
            }
            if (regNum._iuLast == 0)
            {
                return(regNum._uSmall % uDen);
            }
            ulong num = 0L;

            for (int i = regNum._iuLast; i >= 0; i--)
            {
                num = NumericsHelpers.MakeUlong((uint)num, regNum._rgu[i]) % ((ulong)uDen);
            }
            return((uint)num);
        }
Exemplo n.º 7
0
 public void Load(ref BigIntegerBuilder reg, int cuExtra)
 {
     if (reg._iuLast == 0)
     {
         _uSmall = reg._uSmall;
         _iuLast = 0;
     }
     else
     {
         if (!_fWritable || (_rgu.Length <= reg._iuLast))
         {
             _rgu       = new uint[(reg._iuLast + 1) + cuExtra];
             _fWritable = true;
         }
         _iuLast = reg._iuLast;
         Array.Copy(reg._rgu, 0, _rgu, 0, _iuLast + 1);
     }
 }
Exemplo n.º 8
0
 public static void GCD(ref BigIntegerBuilder reg1, ref BigIntegerBuilder reg2)
 {
     if (((reg1._iuLast > 0) && (reg1._rgu[0] == 0)) || ((reg2._iuLast > 0) && (reg2._rgu[0] == 0)))
     {
         int num  = reg1.MakeOdd();
         int num2 = reg2.MakeOdd();
         LehmerGcd(ref reg1, ref reg2);
         int cbit = Math.Min(num, num2);
         if (cbit > 0)
         {
             reg1.ShiftLeft(cbit);
         }
     }
     else
     {
         LehmerGcd(ref reg1, ref reg2);
     }
 }
Exemplo n.º 9
0
 public void Add(ref BigIntegerBuilder reg)
 {
     if (reg._iuLast == 0)
     {
         Add(reg._uSmall);
     }
     else if (_iuLast == 0)
     {
         uint u = _uSmall;
         if (u == 0)
         {
             this = new BigIntegerBuilder(ref reg);
         }
         else
         {
             Load(ref reg, 1);
             Add(u);
         }
     }
     else
     {
         EnsureWritable(Math.Max(_iuLast, reg._iuLast) + 1, 1);
         int iu = reg._iuLast + 1;
         if (_iuLast < reg._iuLast)
         {
             iu = _iuLast + 1;
             Array.Copy(reg._rgu, _iuLast + 1, _rgu, _iuLast + 1, reg._iuLast - _iuLast);
             _iuLast = reg._iuLast;
         }
         uint uCarry = 0;
         for (int i = 0; i < iu; i++)
         {
             uCarry = AddCarry(ref _rgu[i], reg._rgu[i], uCarry);
         }
         if (uCarry != 0)
         {
             ApplyCarry(iu);
         }
     }
 }
Exemplo n.º 10
0
        private void SubRev(ref BigIntegerBuilder reg)
        {
            EnsureWritable(reg._iuLast + 1, 0);
            int iuMin = _iuLast + 1;

            if (_iuLast < reg._iuLast)
            {
                Array.Copy(reg._rgu, _iuLast + 1, _rgu, _iuLast + 1, reg._iuLast - _iuLast);
                _iuLast = reg._iuLast;
            }
            uint uBorrow = 0;

            for (int i = 0; i < iuMin; i++)
            {
                uBorrow = SubRevBorrow(ref _rgu[i], reg._rgu[i], uBorrow);
            }
            if (uBorrow != 0)
            {
                ApplyBorrow(iuMin);
            }
            Trim();
        }
Exemplo n.º 11
0
 private static void ModDivCore(ref BigIntegerBuilder regNum, ref BigIntegerBuilder regDen, bool fQuo, ref BigIntegerBuilder regQuo)
 {
     regQuo.Set((uint)0);
     if (regNum._iuLast >= regDen._iuLast)
     {
         int num   = regDen._iuLast + 1;
         int num2  = regNum._iuLast - regDen._iuLast;
         int cu    = num2;
         int index = regNum._iuLast;
         while (true)
         {
             if (index < num2)
             {
                 cu++;
                 break;
             }
             if (regDen._rgu[index - num2] != regNum._rgu[index])
             {
                 if (regDen._rgu[index - num2] < regNum._rgu[index])
                 {
                     cu++;
                 }
                 break;
             }
             index--;
         }
         if (cu != 0)
         {
             if (fQuo)
             {
                 regQuo.SetSizeLazy(cu);
             }
             uint u    = regDen._rgu[num - 1];
             uint num6 = regDen._rgu[num - 2];
             int  num7 = NumericsHelpers.CbitHighZero(u);
             int  num8 = 0x20 - num7;
             if (num7 > 0)
             {
                 u    = (u << num7) | (num6 >> num8);
                 num6 = num6 << num7;
                 if (num > 2)
                 {
                     num6 |= regDen._rgu[num - 3] >> num8;
                 }
             }
             regNum.EnsureWritable();
             int num9 = cu;
             while (--num9 >= 0)
             {
                 uint  uHi   = ((num9 + num) <= regNum._iuLast) ? regNum._rgu[num9 + num] : 0;
                 ulong num11 = NumericsHelpers.MakeUlong(uHi, regNum._rgu[(num9 + num) - 1]);
                 uint  uLo   = regNum._rgu[(num9 + num) - 2];
                 if (num7 > 0)
                 {
                     num11 = (num11 << num7) | (uLo >> num8);
                     uLo   = uLo << num7;
                     if ((num9 + num) >= 3)
                     {
                         uLo |= regNum._rgu[(num9 + num) - 3] >> num8;
                     }
                 }
                 ulong num13 = num11 / ((ulong)u);
                 ulong num14 = (uint)(num11 % ((ulong)u));
                 if (num13 > 0xffffffffL)
                 {
                     num14 += u * (num13 - 0xffffffffL);
                     num13  = 0xffffffffL;
                 }
                 while ((num14 <= 0xffffffffL) && ((num13 * num6) > NumericsHelpers.MakeUlong((uint)num14, uLo)))
                 {
                     num13 -= (ulong)1L;
                     num14 += u;
                 }
                 if (num13 > 0L)
                 {
                     ulong num15 = 0L;
                     for (int i = 0; i < num; i++)
                     {
                         num15 += regDen._rgu[i] * num13;
                         uint num17 = (uint)num15;
                         num15 = num15 >> 0x20;
                         if (regNum._rgu[num9 + i] < num17)
                         {
                             num15 += (ulong)1L;
                         }
                         regNum._rgu[num9 + i] -= num17;
                     }
                     if (uHi < num15)
                     {
                         uint uCarry = 0;
                         for (int j = 0; j < num; j++)
                         {
                             uCarry = AddCarry(ref regNum._rgu[num9 + j], regDen._rgu[j], uCarry);
                         }
                         num13 -= (ulong)1L;
                     }
                     regNum._iuLast = (num9 + num) - 1;
                 }
                 if (fQuo)
                 {
                     if (cu == 1)
                     {
                         regQuo._uSmall = (uint)num13;
                     }
                     else
                     {
                         regQuo._rgu[num9] = (uint)num13;
                     }
                 }
             }
             regNum._iuLast = num - 1;
             regNum.Trim();
         }
     }
 }
Exemplo n.º 12
0
 public void Mul(ref BigIntegerBuilder reg1, ref BigIntegerBuilder reg2)
 {
     if (reg1._iuLast == 0)
     {
         if (reg2._iuLast == 0)
         {
             Set((ulong)(reg1._uSmall * reg2._uSmall));
         }
         else
         {
             Load(ref reg2, 1);
             Mul(reg1._uSmall);
         }
     }
     else if (reg2._iuLast == 0)
     {
         Load(ref reg1, 1);
         Mul(reg2._uSmall);
     }
     else
     {
         uint[] numArray;
         uint[] numArray2;
         int    num;
         int    num2;
         SetSizeClear((reg1._iuLast + reg2._iuLast) + 2);
         if (reg1.CuNonZero <= reg2.CuNonZero)
         {
             numArray  = reg1._rgu;
             num       = reg1._iuLast + 1;
             numArray2 = reg2._rgu;
             num2      = reg2._iuLast + 1;
         }
         else
         {
             numArray  = reg2._rgu;
             num       = reg2._iuLast + 1;
             numArray2 = reg1._rgu;
             num2      = reg1._iuLast + 1;
         }
         for (int i = 0; i < num; i++)
         {
             uint num4 = numArray[i];
             if (num4 != 0)
             {
                 uint uCarry = 0;
                 int  index  = i;
                 int  num7   = 0;
                 while (num7 < num2)
                 {
                     uCarry = AddMulCarry(ref _rgu[index], num4, numArray2[num7], uCarry);
                     num7++;
                     index++;
                 }
                 while (uCarry != 0)
                 {
                     uCarry = AddCarry(ref _rgu[index++], 0, uCarry);
                 }
             }
         }
         Trim();
     }
 }
Exemplo n.º 13
0
 public void Sub(ref int sign, ref BigIntegerBuilder reg)
 {
     if (reg._iuLast == 0)
     {
         Sub(ref sign, reg._uSmall);
     }
     else if (_iuLast == 0)
     {
         uint u = _uSmall;
         if (u == 0)
         {
             this = new BigIntegerBuilder(ref reg);
         }
         else
         {
             Load(ref reg);
             Sub(ref sign, u);
         }
         sign = -sign;
     }
     else if (_iuLast < reg._iuLast)
     {
         SubRev(ref reg);
         sign = -sign;
     }
     else
     {
         int iuMin = reg._iuLast + 1;
         if (_iuLast == reg._iuLast)
         {
             _iuLast = BigInteger.GetDiffLength(_rgu, reg._rgu, _iuLast + 1) - 1;
             if (_iuLast < 0)
             {
                 _iuLast = 0;
                 _uSmall = 0;
                 return;
             }
             uint num3 = _rgu[_iuLast];
             uint num4 = reg._rgu[_iuLast];
             if (_iuLast == 0)
             {
                 if (num3 < num4)
                 {
                     _uSmall = num4 - num3;
                     sign    = -sign;
                     return;
                 }
                 _uSmall = num3 - num4;
                 return;
             }
             if (num3 < num4)
             {
                 reg._iuLast = _iuLast;
                 SubRev(ref reg);
                 reg._iuLast = iuMin - 1;
                 sign        = -sign;
                 return;
             }
             iuMin = _iuLast + 1;
         }
         EnsureWritable();
         uint uBorrow = 0;
         for (int i = 0; i < iuMin; i++)
         {
             uBorrow = SubBorrow(ref _rgu[i], reg._rgu[i], uBorrow);
         }
         if (uBorrow != 0)
         {
             ApplyBorrow(iuMin);
         }
         Trim();
     }
 }
Exemplo n.º 14
0
 public void Load(ref BigIntegerBuilder reg)
 {
     Load(ref reg, 0);
 }
Exemplo n.º 15
0
        private static void LehmerGcd(ref BigIntegerBuilder reg1, ref BigIntegerBuilder reg2)
        {
            int  num;
            uint num2;
            int  sign = 1;

START:
            num = reg1._iuLast + 1;
            int b = reg2._iuLast + 1;

            if (num < b)
            {
                Py.Core.Util.Swap <BigIntegerBuilder>(ref reg1, ref reg2);
                Py.Core.Util.Swap <int>(ref num, ref b);
            }
            if (b == 1)
            {
                if (num == 1)
                {
                    reg1._uSmall = NumericsHelpers.GCD(reg1._uSmall, reg2._uSmall);
                    return;
                }
                if (reg2._uSmall != 0)
                {
                    reg1.Set(NumericsHelpers.GCD(Mod(ref reg1, reg2._uSmall), reg2._uSmall));
                }
                return;
            }
            if (num == 2)
            {
                reg1.Set(NumericsHelpers.GCD(reg1.GetHigh2(2), reg2.GetHigh2(2)));
                return;
            }
            if (b <= (num - 2))
            {
                reg1.Mod(ref reg2);
                goto START;
            }
            ulong a    = reg1.GetHigh2(num);
            ulong num6 = reg2.GetHigh2(num);
            int   num7 = NumericsHelpers.CbitHighZero((ulong)(a | num6));

            if (num7 > 0)
            {
                a    = (a << num7) | (reg1._rgu[num - 3] >> (0x20 - num7));
                num6 = (num6 << num7) | (reg2._rgu[num - 3] >> (0x20 - num7));
            }
            if (a < num6)
            {
                Py.Core.Util.Swap <ulong>(ref a, ref num6);
                Py.Core.Util.Swap <BigIntegerBuilder>(ref reg1, ref reg2);
            }
            if ((a == ulong.MaxValue) || (num6 == ulong.MaxValue))
            {
                a    = a >> 1;
                num6 = num6 >> 1;
            }
            if (a == num6)
            {
                reg1.Sub(ref sign, ref reg2);
                goto START;
            }
            if (NumericsHelpers.GetHi(num6) == 0)
            {
                reg1.Mod(ref reg2);
                goto START;
            }
            uint num8  = 1;
            uint num9  = 0;
            uint num10 = 0;
            uint num11 = 1;

Label_0162:
            num2 = 1;
            ulong num12 = a - num6;

            while ((num12 >= num6) && (num2 < 0x20))
            {
                num12 -= num6;
                num2++;
            }
            if (num12 >= num6)
            {
                ulong num13 = a / num6;
                if (num13 > 0xffffffffL)
                {
                    goto Label_02A3;
                }
                num2  = (uint)num13;
                num12 = a - (num2 * num6);
            }
            ulong num14 = num8 + (num2 * num10);
            ulong num15 = num9 + (num2 * num11);

            if (((num14 <= 0x7fffffffL) && (num15 <= 0x7fffffffL)) && ((num12 >= num15) && ((num12 + num14) <= (num6 - num10))))
            {
                num8 = (uint)num14;
                num9 = (uint)num15;
                a    = num12;
                if (a > num9)
                {
                    num2  = 1;
                    num12 = num6 - a;
                    while ((num12 >= a) && (num2 < 0x20))
                    {
                        num12 -= a;
                        num2++;
                    }
                    if (num12 >= a)
                    {
                        ulong num16 = num6 / a;
                        if (num16 > 0xffffffffL)
                        {
                            goto Label_02A3;
                        }
                        num2  = (uint)num16;
                        num12 = num6 - (num2 * a);
                    }
                    num14 = num11 + (num2 * num9);
                    num15 = num10 + (num2 * num8);
                    if (((num14 <= 0x7fffffffL) && (num15 <= 0x7fffffffL)) && ((num12 >= num15) && ((num12 + num14) <= (a - num9))))
                    {
                        num11 = (uint)num14;
                        num10 = (uint)num15;
                        num6  = num12;
                        if (num6 > num10)
                        {
                            goto Label_0162;
                        }
                    }
                }
            }
Label_02A3:
            if (num9 == 0)
            {
                if ((a / ((ulong)2L)) >= num6)
                {
                    reg1.Mod(ref reg2);
                }
                else
                {
                    reg1.Sub(ref sign, ref reg2);
                }
            }
            else
            {
                reg1.SetSizeKeep(b, 0);
                reg2.SetSizeKeep(b, 0);
                int num17 = 0;
                int num18 = 0;
                for (int i = 0; i < b; i++)
                {
                    uint num20 = reg1._rgu[i];
                    uint num21 = reg2._rgu[i];
                    long num22 = ((num20 * num8) - (num21 * num9)) + num17;
                    long num23 = ((num21 * num11) - (num20 * num10)) + num18;
                    num17        = (int)(num22 >> 0x20);
                    num18        = (int)(num23 >> 0x20);
                    reg1._rgu[i] = (uint)num22;
                    reg2._rgu[i] = (uint)num23;
                }
                reg1.Trim();
                reg2.Trim();
            }
            goto START;
        }