示例#1
0
 public static int CeilingLogBaseTwo(UInt128 a)
 {
     return(IntegerMath.IsPowerOfTwo(a) ? a.GetBitLength() - 1 : a.GetBitLength());
 }
        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
        }
示例#3
0
 public static int FloorLogBaseTwo(UInt128 a)
 {
     return(a.GetBitLength() - 1);
 }
示例#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
 }