Repository navigation
Factorise past the longs, and decide IsPrime by Miller-Rabin - #2352
Conversation
Factorize, CountDivisors and phi trial-divided over long, and IsPrime was whether the divisor count was 2. Past 2^63 each threw OverflowException, though the first division finds a factor like 2 or 7 at any size, and Simplify folded phi(7^30) to an integer and threw. The loop ran while the divisor's square was at most the running totient, not what was left to factor, so 2^62 took 1.5e9 divisions after the first had divided every 2 out; and past 3037000499 the square wrapped negative, so the largest prime below 2^63 never finished. 2.6.0 does all of this. TryFactorize divides in EInteger as far as 65536, bounded by what is left, asks Primes.IsPrime (Miller-Rabin and Lucas-Lehmer) of the rest, and splits a composite rest by Pollard's rho. phi, the divisor count and Factorize are built on it; where a factor is neither proven prime nor split they throw NotSufficientlySupportedException, and phi(n) in an expression is left as written. IsPrime is Primes.IsPrime, throwing where primality is not decided, and the two phi(p^k) rules fire only where it is proven. The compiled totient, over double and long, takes the same path: its loop wrapped the same way. Closes #2341 Closes #2342 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #2352 +/- ##
==========================================
- Coverage 86.78% 86.75% -0.04%
==========================================
Files 312 312
Lines 68675 68760 +85
Branches 19988 20025 +37
==========================================
+ Hits 59602 59655 +53
- Misses 4905 4921 +16
- Partials 4168 4184 +16
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
MathAllMethods.cs is generated from MathAllMethods.tt, and the Regenerate job rebuilt it with the long overload calling the long Phi this branch removed. The template now writes what the generated file already has. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
These should definitely be queued for v3 (all API insufficiencies like these need to be queued for v3) |
|
Queued in #1019, item 18. 🤖 Generated with Claude Code |
Closes #2341. Closes #2342.
MathS.NumberTheory.Factorize(2^64)OverflowException(2, 64)"phi(7^30)".Simplify()OverflowException19319434534879078361025642, 41 ms(2^89 - 1).IsPrimeOverflowExceptiontrueFactorize(9223372036854775783), the largest prime below 2^63phi(2^62)Factorize(1000000007 * 1000000009)TryFactorize: trial division inEIntegerup to 65536, bounded by what is left to factor rather than by the running totient. ThenPrimes.IsPrime(Primality is decided by Miller-Rabin and Lucas-Lehmer, and finishes #2232's Miller–Rabin and Lucas–Lehmer) is asked of the rest, and Pollard's rho splits a rest that is composite. A rest above 65536² with no factor below it is prime once proven so, or its two pieces are each past 65536.phi,CountDivisorsandFactorizeare built on it. Where a factor is neither proven prime nor split (an undecided probable prime past ψ13, or a composite rho does not split within its budget), the public methods throwNotSufficientlySupportedException.phi(n)in an expression is left as written instead of throwing out ofSimplify, as the issue asks.Integer.IsPrimeisPrimes.IsPrime, asPPmembership is. That isbool?internally. The publicboolthrows where primality is not decided, rather than becomingbool?, which would break the API. The twophi(p ^ k)rules (the matched one and the pattern) fire only where primality is proven.double,longandinthad the same wrapping loop and now takes the same path. Thelongoverload ofPhiis gone; it had no caller left.Tests:
AFactorisationPastTheLongsTest, 24 cases, each expected value checked with sympy. 12 fail on master (four by the 30 s cap); the 12 small cases pass on both. The full suite, AOT and the nine harnesses pass. There is a BREAKING-CHANGES entry, measured on 2.6.0.🤖 Generated with Claude Code