public static MutableInteger SetGreatestCommonDivisor(this MutableInteger c, MutableInteger a, MutableInteger b, MutableIntegerStore store)
 {
     var reg1 = store.Allocate();
     if (a.IsZero)
         c.Set(b);
     else if (b.IsZero)
         c.Set(a);
     else
     {
         reg1.Set(a);
         c.Set(b);
         while (true)
         {
             reg1.Modulo(c);
             if (reg1.IsZero)
                 break;
             c.Modulo(reg1);
             if (c.IsZero)
             {
                 c.Set(reg1);
                 break;
             }
         }
     }
     store.Release(reg1);
     return c;
 }
        public static MutableInteger SetModularInverse(this MutableInteger c, MutableInteger a, MutableInteger b, MutableIntegerStore store)
        {
            var p = store.Allocate().Set(a);
            var q = store.Allocate().Set(b);
            var x0 = store.Allocate().Set(1);
            var x1 = store.Allocate().Set(0);
            var quotient = store.Allocate();
            var remainder = store.Allocate();
            var product = store.Allocate();

            while (!q.IsZero)
            {
                remainder.Set(p).ModuloWithQuotient(q, quotient);
                var tmpp = p;
                p = q;
                q = tmpp.Set(remainder);
                var tmpx = x1;
                x1 = x0.Subtract(product.SetProduct(quotient, x1));
                x0 = tmpx;
            }
            c.Set(x0);
            if (c.Sign == -1)
                c.Add(b);

            store.Release(p);
            store.Release(q);
            store.Release(x0);
            store.Release(x1);
            store.Release(quotient);
            store.Release(remainder);
            return c;
        }
 public static MutableInteger SetModularInversePowerOfTwoModulus(this MutableInteger c, MutableInteger d, int n, MutableIntegerStore store)
 {
     // See 9.2 in: http://gmplib.org/~tege/divcnst-pldi94.pdf
     c.Set(d);
     var two = store.Allocate().Set(2);
     var reg1 = store.Allocate();
     var reg2 = store.Allocate();
     for (int m = 3; m < n; m *= 2)
     {
         reg1.Set(c);
         reg2.SetProduct(reg1, d);
         reg2.Mask(n);
         reg2.SetDifference(two, reg2);
         c.SetProduct(reg1, reg2);
         c.Mask(n);
     }
     if (c.Sign == -1)
         c.Add(reg1.Set(1).LeftShift(n));
     store.Release(two);
     store.Release(reg1);
     store.Release(reg2);
     return c;
 }
Example #4
0
 private int TauSumInnerWorkerLarge(UInt128 y, ulong imin, ulong imax)
 {
     #if false
     var sum = (uint)0;
     for (var i = imin; i < imax; i++)
         sum ^= (uint)(y / i);
     return (int)(sum & 1);
     #endif
     #if false
     var yRep = (MutableInteger)y;
     var xRep = yRep.Copy();
     var iRep = (MutableInteger)imin;
     var store = new MutableIntegerStore(4);
     var sum = (uint)0;
     for (var i = imin; i < imax; i++)
     {
         sum ^= xRep.Set(yRep).Divide(iRep, store).LeastSignificantWord;
         iRep.Increment();
     }
     return (int)(sum & 1);
     #endif
     #if false
     // The quantity floor(y/d) is odd iff y mod 2d >= d.
     var sum = (ulong)0;
     for (var i = imin; i < imax; i++)
         sum ^= y % (i << 1) - i;
     sum >>= 63;
     if (((imax - imin) & 1) != 0)
         sum ^= 1;
     return (int)(sum & 1);
     #endif
     #if false
     if (y.IsPowerOfTwo)
     {
         var uBits = y.GetBitLength() - 32;
         var sum = (uint)0;
         var y0 = (UInt128)y.LeastSignificantWord;
         var y12 = (ulong)(y >> 32);
         for (var i = imin; i < imax; i++)
         {
             var y12mod = y12 % i;
             var yPrime = y0 + ((y12 % i) << 32);
             var shift = 64 - i.GetBitCount();
             sum ^= (uint)(y / i);
         }
         return (int)(sum & 1);
     }
     #endif
     #if false
     var sum = (uint)0;
     var i = imax - 1;
     var current = (ulong)(y / (i + 1));
     var delta = (ulong)(y / i - current);
     var mod = (long)(y - (UInt128)current * (i + 1));
     var imid = Math.Max(imin, (ulong)(y >> (64 - safetyBits)));
     while (i >= imid)
     {
         mod += (long)(current - delta * i);
         current += delta;
         if (mod >= (long)i)
         {
             ++delta;
             ++current;
             mod -= (long)i;
             if (mod >= (long)i)
                 break;
         }
         else if (mod < 0)
         {
             --delta;
             --current;
             mod += (long)i;
         }
         Debug.Assert(y / i == current);
         sum ^= (uint)current;
         --i;
     }
     while (i >= imin)
     {
         sum ^= (uint)(y / i);
         --i;
     }
     return (int)(sum & 1);
     #endif
     #if true
     var sum = (uint)0;
     var i = imax - 1;
     var current = (ulong)(y / (i + 1));
     var delta = (ulong)(y / i) - current;
     var mod = (long)(y - (UInt128)current * (i + 1));
     var imid = Math.Max(imin, (ulong)(y >> (64 - safetyBits)));
     var deltai = delta * (i + 1);
     while (i >= imid)
     {
         deltai -= delta;
         mod += (long)(current - deltai);
         if (mod >= (long)i)
         {
             ++delta;
             deltai += i;
             mod -= (long)i;
             if (mod >= (long)i)
                 break;
         }
         else if (mod < 0)
         {
             --delta;
             deltai -= i;
             mod += (long)i;
         }
         current += delta;
         Debug.Assert(y / i == current);
         sum ^= (uint)current;
         --i;
     }
     while (i >= imin)
     {
         sum ^= (uint)(y / i);
         --i;
     }
     return (int)(sum & 1);
     #endif
 }