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 }
public static int FloorLogBaseTwo(UInt128 a) { return(a.GetBitLength() - 1); }
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 }