Restore Math.Sqrt heuristic bound

This commit is contained in:
Marek Lemańczyk committed 2025-10-29 01:43:12 +01:00
1 parent 5a9e103bd5
commit f49963c4f6
2 files changed
+26 -42

No files matched your search

@@ -306,33 +306,25 @@ Cleanup:
internal static ulong ComputeHeuristicSqrt(ulong n) internal static ulong ComputeHeuristicSqrt(ulong n)
{ {
if (n < 2UL) ulong sqrt = (ulong)Math.Sqrt(n);
UInt128 square = (UInt128)sqrt * sqrt;
while (square > n)
{ {
return n; sqrt--;
square = (UInt128)sqrt * sqrt;
} }
int log2 = BitOperations.Log2(n); ulong next = sqrt + 1UL;
ulong estimate = 1UL << ((log2 + 1) >> 1); UInt128 nextSquare = (UInt128)next * next;
ulong quotient = n / estimate; while (nextSquare <= n)
while (estimate > quotient)
{ {
estimate = (estimate + quotient) >> 1; sqrt = next;
quotient = n / estimate; next++;
nextSquare = (UInt128)next * next;
} }
while (true) return sqrt;
{
ulong nextEstimate = estimate + 1UL;
if (nextEstimate > n / nextEstimate)
{
break;
}
estimate = nextEstimate;
}
return estimate;
} }
private static ReadOnlySpan<uint> GetCombinedDivisors(byte nMod10) private static ReadOnlySpan<uint> GetCombinedDivisors(byte nMod10)
+13 -21
View File
@@ -431,33 +431,25 @@ Cleanup:
internal static ulong ComputeHeuristicSqrt(ulong n) internal static ulong ComputeHeuristicSqrt(ulong n)
{ {
if (n < 2UL) ulong sqrt = (ulong)Math.Sqrt(n);
UInt128 square = (UInt128)sqrt * sqrt;
while (square > n)
{ {
return n; sqrt--;
square = (UInt128)sqrt * sqrt;
} }
int log2 = BitOperations.Log2(n); ulong next = sqrt + 1UL;
ulong estimate = 1UL << ((log2 + 1) >> 1); UInt128 nextSquare = (UInt128)next * next;
ulong quotient = n / estimate; while (nextSquare <= n)
while (estimate > quotient)
{ {
estimate = (estimate + quotient) >> 1; sqrt = next;
quotient = n / estimate; next++;
nextSquare = (UInt128)next * next;
} }
while (true) return sqrt;
{
ulong nextEstimate = estimate + 1UL;
if (nextEstimate > n / nextEstimate)
{
break;
}
estimate = nextEstimate;
}
return estimate;
} }
private static ReadOnlySpan<byte> GetGroupBEndingOrder(byte nMod10) => nMod10 switch private static ReadOnlySpan<byte> GetGroupBEndingOrder(byte nMod10) => nMod10 switch