diff --git a/PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs b/PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs index 96e5d12..d7f245c 100644 --- a/PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs +++ b/PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs @@ -112,7 +112,7 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv Dictionary? current = cache; if (current is null) { - current = ThreadStaticPools.TakeMersenneFactorCacheDictionary(); + current = ThreadStaticPools.RentMersenneFactorCacheDictionary(); cache = current; } @@ -149,11 +149,6 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv // } UInt128 step = (UInt128)prime << 1; - if (step == UInt128.Zero) - { - processedAll = true; - return false; - } UInt128 limit = allowedMax; UInt128 divisor = step + UInt128.One; diff --git a/PerfectNumbers.Core/MersenneDivisorCycles.cs b/PerfectNumbers.Core/MersenneDivisorCycles.cs index eab0187..66dc9bc 100644 --- a/PerfectNumbers.Core/MersenneDivisorCycles.cs +++ b/PerfectNumbers.Core/MersenneDivisorCycles.cs @@ -23,26 +23,6 @@ public class MersenneDivisorCycles { } - private static Dictionary RentFactorCountDictionary() - { - return ThreadStaticPools.TakeFactorCountDictionary(); - } - - private static void ReturnFactorCountDictionary(Dictionary dictionary) - { - ThreadStaticPools.ReturnFactorCountDictionary(dictionary); - } - - private static Dictionary RentFactorScratchDictionary() - { - return ThreadStaticPools.TakeFactorScratchDictionary(); - } - - private static void ReturnFactorScratchDictionary(Dictionary dictionary) - { - ThreadStaticPools.ReturnFactorScratchDictionary(dictionary); - } - public void LoadFrom(string path) { EnsureSmallBuffer(); @@ -317,10 +297,6 @@ public class MersenneDivisorCycles } ulong phi = divisor - 1UL; - if (phi == 0UL) - { - return false; - } int twoCount = BitOperations.TrailingZeroCount(phi); ulong reducedPhi = phi >> twoCount; @@ -330,12 +306,8 @@ public class MersenneDivisorCycles } ulong k = reducedPhi / exponent; - if (k == 0UL) - { - return false; - } - Dictionary factorCounts = RentFactorCountDictionary(); + Dictionary factorCounts = ThreadStaticPools.RentFactorCountDictionary(); try { @@ -354,7 +326,7 @@ public class MersenneDivisorCycles } finally { - ReturnFactorCountDictionary(factorCounts); + ThreadStaticPools.ReturnFactorCountDictionary(factorCounts); } } @@ -397,7 +369,7 @@ public class MersenneDivisorCycles return true; } - Dictionary scratch = RentFactorScratchDictionary(); + Dictionary scratch = ThreadStaticPools.RentFactorScratchDictionary(); try { @@ -430,18 +402,12 @@ public class MersenneDivisorCycles } finally { - ReturnFactorScratchDictionary(scratch); + ThreadStaticPools.ReturnFactorScratchDictionary(scratch); } } private static bool TryFactorIntoCountsInternal(ulong value, Dictionary counts) { - // This guard terminates the recursion once Pollard-Rho factorization has reduced the input to 1. - if (value <= 1UL) - { - return true; - } - ulong remaining = value; uint[] smallPrimes = PrimesGenerator.SmallPrimes; ulong[] smallPrimesSquared = PrimesGenerator.SmallPrimesPow2; @@ -480,7 +446,18 @@ public class MersenneDivisorCycles } ulong quotient = remaining / factor; - return TryFactorIntoCountsInternal(factor, counts) && TryFactorIntoCountsInternal(quotient, counts); + if (factor > 1UL && !TryFactorIntoCountsInternal(factor, counts)) + { + return false; + } + + // Guard the recursive calls to terminate once Pollard-Rho reduces either branch to 1. + if (quotient > 1UL && !TryFactorIntoCountsInternal(quotient, counts)) + { + return false; + } + + return true; } private static void AddFactor(Dictionary counts, ulong factor) diff --git a/PerfectNumbers.Core/ThreadStaticPools.cs b/PerfectNumbers.Core/ThreadStaticPools.cs index a953ec7..a846ba8 100644 --- a/PerfectNumbers.Core/ThreadStaticPools.cs +++ b/PerfectNumbers.Core/ThreadStaticPools.cs @@ -47,7 +47,7 @@ namespace PerfectNumbers.Core private static Dictionary? _mersenneFactorCacheDictionary; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Dictionary TakeMersenneFactorCacheDictionary() + public static Dictionary RentMersenneFactorCacheDictionary() { Dictionary? cache = _mersenneFactorCacheDictionary; if (cache is null) @@ -71,7 +71,7 @@ namespace PerfectNumbers.Core private static Dictionary? _factorCountDictionary; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Dictionary TakeFactorCountDictionary() + public static Dictionary RentFactorCountDictionary() { Dictionary? dictionary = _factorCountDictionary; if (dictionary is null) @@ -95,7 +95,7 @@ namespace PerfectNumbers.Core private static Dictionary? _factorScratchDictionary; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Dictionary TakeFactorScratchDictionary() + public static Dictionary RentFactorScratchDictionary() { Dictionary? dictionary = _factorScratchDictionary; if (dictionary is null)