diff --git a/PerfectNumbers.Core/UInt128Extensions.cs b/PerfectNumbers.Core/UInt128Extensions.cs index 904d84c..99fda8a 100644 --- a/PerfectNumbers.Core/UInt128Extensions.cs +++ b/PerfectNumbers.Core/UInt128Extensions.cs @@ -121,44 +121,48 @@ public static class UInt128Extensions } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Mod10_8_5_3(this UInt128 value, out ulong mod10, out ulong mod8, out ulong mod5, out ulong mod3) - { - UInt128 temp = value; - uint byteSum = 0U; + public static void Mod10_8_5_3(this UInt128 value, out ulong mod10, out ulong mod8, out ulong mod5, out ulong mod3) + { + UInt128 temp = UInt128.Zero; + uint byteSum = 0U; + byte current = 0; + uint accumulator = 0U; - do - { - byteSum += (byte)temp; - temp >>= 8; - } - while (temp != UInt128.Zero); + temp = value; + do + { + current = (byte)temp; + byteSum += current; + temp >>= 8; + } + while (temp != UInt128.Zero); - mod8 = (ulong)value & 7UL; - - uint mod5Value = byteSum.Mod5(); - uint mod3Value = byteSum.Mod3(); + mod8 = (ulong)value & 7UL; + accumulator = byteSum.Mod5(); + mod5 = accumulator; mod10 = (mod8 & 1UL) == 0UL - ? mod5Value switch + ? accumulator switch { 0U => 0UL, 1U => 6UL, - 2U => 2UL, - 3U => 8UL, - _ => 4UL, - } - : mod5Value switch - { - 0U => 5UL, - 1U => 1UL, - 2U => 7UL, - 3U => 3UL, - _ => 9UL, - }; + 2U => 2UL, + 3U => 8UL, + _ => 4UL, + } + : accumulator switch + { + 0U => 5UL, + 1U => 1UL, + 2U => 7UL, + 3U => 3UL, + _ => 9UL, + }; - mod5 = mod5Value; - mod3 = mod3Value; - } + // Reusing accumulator to hold the mod 3 reduction now that the mod 5 value has been stored. + accumulator = byteSum.Mod3(); + mod3 = accumulator; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static UInt128 Pow(this UInt128 value, ulong exponent) diff --git a/PerfectNumbers.Core/UIntExtensions.cs b/PerfectNumbers.Core/UIntExtensions.cs index d17afa0..3706e18 100644 --- a/PerfectNumbers.Core/UIntExtensions.cs +++ b/PerfectNumbers.Core/UIntExtensions.cs @@ -9,15 +9,29 @@ public static class UIntExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint Mod3(this uint value) { - uint quotient = (uint)(((ulong)value * 0xAAAAAAABUL) >> 33); - return value - quotient * 3U; + ulong wideValue = 0UL; + uint quotient = 0U; + uint remainder = 0U; + + wideValue = (ulong)value * 0xAAAAAAABUL; + quotient = (uint)(wideValue >> 33); + remainder = value - quotient * 3U; + + return remainder; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint Mod5(this uint value) { - uint quotient = (uint)(((ulong)value * 0xCCCCCCCDUL) >> 34); - return value - quotient * 5U; + ulong wideValue = 0UL; + uint quotient = 0U; + uint remainder = 0U; + + wideValue = (ulong)value * 0xCCCCCCCDUL; + quotient = (uint)(wideValue >> 34); + remainder = value - quotient * 5U; + + return remainder; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -30,11 +44,14 @@ public static class UIntExtensions public static uint Mod7(this uint value) { uint remainder = 0U; - uint temp = value; + uint temp = 0U; + uint chunk = 0U; + temp = value; while (temp != 0U) { - remainder += temp & 7U; + chunk = temp & 7U; + remainder += chunk; temp >>= 3; if (remainder >= 7U) { @@ -51,18 +68,29 @@ public static class UIntExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint Mod10(this uint value) { - return value - (uint)(((ulong)value * 0xCCCCCCCDUL) >> 35) * 10U; + ulong wideValue = 0UL; + uint quotient = 0U; + uint remainder = 0U; + + wideValue = (ulong)value * 0xCCCCCCCDUL; + quotient = (uint)(wideValue >> 35); + remainder = value - quotient * 10U; + + return remainder; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint Mod11(this uint value) { uint remainder = 0U; - uint temp = value; + uint temp = 0U; + uint chunk = 0U; + temp = value; while (temp != 0U) { - remainder += temp & 1023U; + chunk = temp & 1023U; + remainder += chunk; temp >>= 10; remainder -= 11U * (remainder / 11U); } diff --git a/PerfectNumbers.Core/ULongExtensions.cs b/PerfectNumbers.Core/ULongExtensions.cs index a9f6837..61fa6f4 100644 --- a/PerfectNumbers.Core/ULongExtensions.cs +++ b/PerfectNumbers.Core/ULongExtensions.cs @@ -64,23 +64,26 @@ public static class ULongExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mod10_8_5_3(this ulong value, out ulong mod10, out ulong mod8, out ulong mod5, out ulong mod3) { - ulong temp = value; + ulong temp = 0UL; uint byteSum = 0U; + byte current = 0; + uint accumulator = 0U; + temp = value; do { - byteSum += (byte)temp; + current = (byte)temp; + byteSum += current; temp >>= 8; } while (temp != 0UL); mod8 = value & 7UL; - uint mod5Value = byteSum.Mod5(); - uint mod3Value = byteSum.Mod3(); - + accumulator = byteSum.Mod5(); + mod5 = accumulator; mod10 = (mod8 & 1UL) == 0UL - ? mod5Value switch + ? accumulator switch { 0U => 0UL, 1U => 6UL, @@ -88,7 +91,7 @@ public static class ULongExtensions 3U => 8UL, _ => 4UL, } - : mod5Value switch + : accumulator switch { 0U => 5UL, 1U => 1UL, @@ -97,8 +100,9 @@ public static class ULongExtensions _ => 9UL, }; - mod5 = mod5Value; - mod3 = mod3Value; + // Reusing accumulator to hold the mod 3 reduction now that the mod 5 value has been stored. + accumulator = byteSum.Mod3(); + mod3 = accumulator; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -108,12 +112,14 @@ public static class ULongExtensions uint mod5Accumulator = 0U; uint mod7Accumulator = 0U; uint mod11Accumulator = 0U; - ulong temp = value; + ulong temp = 0UL; int index = 0; + byte current = 0; + temp = value; do { - byte current = (byte)temp; + current = (byte)temp; mod3Accumulator += current; mod5Accumulator += current; mod7Accumulator += (uint)(current * Mod7ByteCoefficients[index]); @@ -124,16 +130,30 @@ public static class ULongExtensions } while (temp != 0UL); - mod3 = mod3Accumulator.Mod3(); - mod5 = mod5Accumulator.Mod5(); - mod7 = ReduceMod7(mod7Accumulator); - mod11 = ReduceMod11(mod11Accumulator); + // Reusing mod3Accumulator to store the reduced mod 3 remainder before exposing it. + mod3Accumulator = mod3Accumulator.Mod3(); + // Reusing mod5Accumulator to store the reduced mod 5 remainder before exposing it. + mod5Accumulator = mod5Accumulator.Mod5(); + // Reusing mod7Accumulator to store the reduced mod 7 remainder before exposing it. + mod7Accumulator = (uint)ReduceMod7(mod7Accumulator); + // Reusing mod11Accumulator to store the reduced mod 11 remainder before exposing it. + mod11Accumulator = (uint)ReduceMod11(mod11Accumulator); + + mod3 = mod3Accumulator; + mod5 = mod5Accumulator; + mod7 = mod7Accumulator; + mod11 = mod11Accumulator; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mod10_8_5_3Steps(this ulong value, out ulong step10, out ulong step8, out ulong step5, out ulong step3) { - value.Mod10_8_5_3(out ulong mod10, out ulong mod8, out ulong mod5, out ulong mod3); + ulong mod10 = 0UL; + ulong mod8 = 0UL; + ulong mod5 = 0UL; + ulong mod3 = 0UL; + + value.Mod10_8_5_3(out mod10, out mod8, out mod5, out mod3); step10 = (mod10 << 1).Mod10(); step8 = ((mod8 << 1) & 7UL); @@ -145,35 +165,38 @@ public static class ULongExtensions public static bool IsPrimeCandidate(this ulong n) { int i = 0; - ulong p; - uint[] smallPrimes = PrimesGenerator.SmallPrimes; - ulong[] smallPrimesPow2 = PrimesGenerator.SmallPrimesPow2; - int len = smallPrimes.Length; - for (; i < len; i++) - { - if (smallPrimesPow2[i] > n) - { - break; - } + ulong p = 0UL; + uint[] smallPrimes = PrimesGenerator.SmallPrimes; + ulong[] smallPrimesPow2 = PrimesGenerator.SmallPrimesPow2; + int len = smallPrimes.Length; + for (; i < len; i++) + { + if (smallPrimesPow2[i] > n) + { + break; + } - p = smallPrimes[i]; - if ((n % p) == 0UL) - { - return n == p; - } - } + p = smallPrimes[i]; + if ((n % p) == 0UL) + { + return n == p; + } + } - return true; - } + return true; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong Mod10(this ulong value) { - ulong mod5 = value.Mod5(); + ulong mod5 = 0UL; + ulong result = 0UL; + + mod5 = value.Mod5(); if ((value & 1UL) == 0UL) { - return mod5 switch + result = mod5 switch { 0UL => 0UL, 1UL => 6UL, @@ -182,15 +205,19 @@ public static class ULongExtensions _ => 4UL, }; } - - return mod5 switch + else { - 0UL => 5UL, - 1UL => 1UL, - 2UL => 7UL, - 3UL => 3UL, - _ => 9UL, - }; + result = mod5 switch + { + 0UL => 5UL, + 1UL => 1UL, + 2UL => 7UL, + 3UL => 3UL, + _ => 9UL, + }; + } + + return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -199,10 +226,17 @@ public static class ULongExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong Mod3(this ulong value) { - uint sum = (uint)(value & 0xFFFFUL); - sum += (uint)((value >> 16) & 0xFFFFUL); - sum += (uint)((value >> 32) & 0xFFFFUL); - sum += (uint)((value >> 48) & 0xFFFFUL); + uint sum = 0U; + ulong temp = 0UL; + + temp = value & 0xFFFFUL; + sum = (uint)temp; + temp = (value >> 16) & 0xFFFFUL; + sum += (uint)temp; + temp = (value >> 32) & 0xFFFFUL; + sum += (uint)temp; + temp = (value >> 48) & 0xFFFFUL; + sum += (uint)temp; return sum.Mod3(); } @@ -210,10 +244,17 @@ public static class ULongExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong Mod5(this ulong value) { - uint sum = (uint)(value & 0xFFFFUL); - sum += (uint)((value >> 16) & 0xFFFFUL); - sum += (uint)((value >> 32) & 0xFFFFUL); - sum += (uint)((value >> 48) & 0xFFFFUL); + uint sum = 0U; + ulong temp = 0UL; + + temp = value & 0xFFFFUL; + sum = (uint)temp; + temp = (value >> 16) & 0xFFFFUL; + sum += (uint)temp; + temp = (value >> 32) & 0xFFFFUL; + sum += (uint)temp; + temp = (value >> 48) & 0xFFFFUL; + sum += (uint)temp; return sum.Mod5(); } @@ -227,10 +268,14 @@ public static class ULongExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong Mod7(this ulong value) { - uint low = (uint)value; - uint high = (uint)(value >> 32); + uint low = 0U; + uint high = 0U; + ulong remainder = 0UL; - ulong remainder = low.Mod7() + (ulong)high.Mod7() * 4UL; + low = (uint)value; + high = (uint)(value >> 32); + + remainder = low.Mod7() + (ulong)high.Mod7() * 4UL; while (remainder >= 7UL) { remainder -= 7UL; @@ -242,10 +287,14 @@ public static class ULongExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong Mod11(this ulong value) { - uint low = (uint)value; - uint high = (uint)(value >> 32); + uint low = 0U; + uint high = 0U; + ulong remainder = 0UL; - ulong remainder = low.Mod11() + (ulong)high.Mod11() * 4UL; + low = (uint)value; + high = (uint)(value >> 32); + + remainder = low.Mod11() + (ulong)high.Mod11() * 4UL; while (remainder >= 11UL) { remainder -= 11UL;