diff --git a/PerfectNumbers.Core/UInt128Extensions.cs b/PerfectNumbers.Core/UInt128Extensions.cs index bfc18d7..c55e483 100644 --- a/PerfectNumbers.Core/UInt128Extensions.cs +++ b/PerfectNumbers.Core/UInt128Extensions.cs @@ -677,15 +677,25 @@ public static class UInt128Extensions // return UInt128.Zero; // } - value %= modulus; - addend %= modulus; - if (addend == UInt128.Zero) - { - return value; - } + // value and addend already lie below the modulus throughout the divisor-by-divisor CPU flow, + // so skip the redundant reductions the old helper performed. + // value %= modulus; + // addend %= modulus; + // Odd moduli keep 2^delta from landing on zero, leaving this branch inactive in the scan. + // if (addend == UInt128.Zero) + // { + // return value; + // } UInt128 threshold = modulus - addend; - return value >= threshold ? value - threshold : value + addend; + if (value >= threshold) + { + return value - threshold; + } + + UInt128 sum = value + addend; + // The sum stays below the modulus under the threshold guard above, so no wraparound occurs. + return sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/PerfectNumbers.Core/ULongExtensions.cs b/PerfectNumbers.Core/ULongExtensions.cs index dd8e040..2de1e01 100644 --- a/PerfectNumbers.Core/ULongExtensions.cs +++ b/PerfectNumbers.Core/ULongExtensions.cs @@ -464,17 +464,20 @@ public static partial class ULongExtensions // return 0UL; // } + // The Pollard Rho walks keep both operands below the modulus, so skip re-folding them here. UInt128 sum = (UInt128)value + addend; - UInt128 mod = modulus; - if (sum >= mod) + if (sum < modulus) { - sum -= mod; - if (sum >= mod) - { - sum -= mod; - } + return (ulong)sum; } + sum -= modulus; + // After one subtraction the sum always falls below the modulus on this path, making the old guard redundant. + // if (sum >= modulus) + // { + // sum -= modulus; + // } + return (ulong)sum; }