Reuse local variables across modulo helpers

This commit is contained in:
Marek Lemańczyk committed 2025-09-22 19:54:59 +02:00
1 parent 3b8a10a20b
commit 762d205e86
3 files changed
+178 -97

No files matched your search

+107 -58
View File
@@ -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;