Reuse local variables across modulo helpers
This commit is contained in:
1 parent
3b8a10a20b
commit
762d205e86
3 files changed
+134
-53
No files matched your search
@@ -123,23 +123,26 @@ public static class UInt128Extensions
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void Mod10_8_5_3(this UInt128 value, out ulong mod10, out ulong mod8, out ulong mod5, out ulong mod3)
|
public static void Mod10_8_5_3(this UInt128 value, out ulong mod10, out ulong mod8, out ulong mod5, out ulong mod3)
|
||||||
{
|
{
|
||||||
UInt128 temp = value;
|
UInt128 temp = UInt128.Zero;
|
||||||
uint byteSum = 0U;
|
uint byteSum = 0U;
|
||||||
|
byte current = 0;
|
||||||
|
uint accumulator = 0U;
|
||||||
|
|
||||||
|
temp = value;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
byteSum += (byte)temp;
|
current = (byte)temp;
|
||||||
|
byteSum += current;
|
||||||
temp >>= 8;
|
temp >>= 8;
|
||||||
}
|
}
|
||||||
while (temp != UInt128.Zero);
|
while (temp != UInt128.Zero);
|
||||||
|
|
||||||
mod8 = (ulong)value & 7UL;
|
mod8 = (ulong)value & 7UL;
|
||||||
|
|
||||||
uint mod5Value = byteSum.Mod5();
|
accumulator = byteSum.Mod5();
|
||||||
uint mod3Value = byteSum.Mod3();
|
mod5 = accumulator;
|
||||||
|
|
||||||
mod10 = (mod8 & 1UL) == 0UL
|
mod10 = (mod8 & 1UL) == 0UL
|
||||||
? mod5Value switch
|
? accumulator switch
|
||||||
{
|
{
|
||||||
0U => 0UL,
|
0U => 0UL,
|
||||||
1U => 6UL,
|
1U => 6UL,
|
||||||
@@ -147,7 +150,7 @@ public static class UInt128Extensions
|
|||||||
3U => 8UL,
|
3U => 8UL,
|
||||||
_ => 4UL,
|
_ => 4UL,
|
||||||
}
|
}
|
||||||
: mod5Value switch
|
: accumulator switch
|
||||||
{
|
{
|
||||||
0U => 5UL,
|
0U => 5UL,
|
||||||
1U => 1UL,
|
1U => 1UL,
|
||||||
@@ -156,8 +159,9 @@ public static class UInt128Extensions
|
|||||||
_ => 9UL,
|
_ => 9UL,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod5 = mod5Value;
|
// Reusing accumulator to hold the mod 3 reduction now that the mod 5 value has been stored.
|
||||||
mod3 = mod3Value;
|
accumulator = byteSum.Mod3();
|
||||||
|
mod3 = accumulator;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -9,15 +9,29 @@ public static class UIntExtensions
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static uint Mod3(this uint value)
|
public static uint Mod3(this uint value)
|
||||||
{
|
{
|
||||||
uint quotient = (uint)(((ulong)value * 0xAAAAAAABUL) >> 33);
|
ulong wideValue = 0UL;
|
||||||
return value - quotient * 3U;
|
uint quotient = 0U;
|
||||||
|
uint remainder = 0U;
|
||||||
|
|
||||||
|
wideValue = (ulong)value * 0xAAAAAAABUL;
|
||||||
|
quotient = (uint)(wideValue >> 33);
|
||||||
|
remainder = value - quotient * 3U;
|
||||||
|
|
||||||
|
return remainder;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static uint Mod5(this uint value)
|
public static uint Mod5(this uint value)
|
||||||
{
|
{
|
||||||
uint quotient = (uint)(((ulong)value * 0xCCCCCCCDUL) >> 34);
|
ulong wideValue = 0UL;
|
||||||
return value - quotient * 5U;
|
uint quotient = 0U;
|
||||||
|
uint remainder = 0U;
|
||||||
|
|
||||||
|
wideValue = (ulong)value * 0xCCCCCCCDUL;
|
||||||
|
quotient = (uint)(wideValue >> 34);
|
||||||
|
remainder = value - quotient * 5U;
|
||||||
|
|
||||||
|
return remainder;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -30,11 +44,14 @@ public static class UIntExtensions
|
|||||||
public static uint Mod7(this uint value)
|
public static uint Mod7(this uint value)
|
||||||
{
|
{
|
||||||
uint remainder = 0U;
|
uint remainder = 0U;
|
||||||
uint temp = value;
|
uint temp = 0U;
|
||||||
|
uint chunk = 0U;
|
||||||
|
|
||||||
|
temp = value;
|
||||||
while (temp != 0U)
|
while (temp != 0U)
|
||||||
{
|
{
|
||||||
remainder += temp & 7U;
|
chunk = temp & 7U;
|
||||||
|
remainder += chunk;
|
||||||
temp >>= 3;
|
temp >>= 3;
|
||||||
if (remainder >= 7U)
|
if (remainder >= 7U)
|
||||||
{
|
{
|
||||||
@@ -51,18 +68,29 @@ public static class UIntExtensions
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static uint Mod10(this uint value)
|
public static uint Mod10(this uint value)
|
||||||
{
|
{
|
||||||
return value - (uint)(((ulong)value * 0xCCCCCCCDUL) >> 35) * 10U;
|
ulong wideValue = 0UL;
|
||||||
|
uint quotient = 0U;
|
||||||
|
uint remainder = 0U;
|
||||||
|
|
||||||
|
wideValue = (ulong)value * 0xCCCCCCCDUL;
|
||||||
|
quotient = (uint)(wideValue >> 35);
|
||||||
|
remainder = value - quotient * 10U;
|
||||||
|
|
||||||
|
return remainder;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static uint Mod11(this uint value)
|
public static uint Mod11(this uint value)
|
||||||
{
|
{
|
||||||
uint remainder = 0U;
|
uint remainder = 0U;
|
||||||
uint temp = value;
|
uint temp = 0U;
|
||||||
|
uint chunk = 0U;
|
||||||
|
|
||||||
|
temp = value;
|
||||||
while (temp != 0U)
|
while (temp != 0U)
|
||||||
{
|
{
|
||||||
remainder += temp & 1023U;
|
chunk = temp & 1023U;
|
||||||
|
remainder += chunk;
|
||||||
temp >>= 10;
|
temp >>= 10;
|
||||||
remainder -= 11U * (remainder / 11U);
|
remainder -= 11U * (remainder / 11U);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,23 +64,26 @@ public static class ULongExtensions
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[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)
|
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;
|
uint byteSum = 0U;
|
||||||
|
byte current = 0;
|
||||||
|
uint accumulator = 0U;
|
||||||
|
|
||||||
|
temp = value;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
byteSum += (byte)temp;
|
current = (byte)temp;
|
||||||
|
byteSum += current;
|
||||||
temp >>= 8;
|
temp >>= 8;
|
||||||
}
|
}
|
||||||
while (temp != 0UL);
|
while (temp != 0UL);
|
||||||
|
|
||||||
mod8 = value & 7UL;
|
mod8 = value & 7UL;
|
||||||
|
|
||||||
uint mod5Value = byteSum.Mod5();
|
accumulator = byteSum.Mod5();
|
||||||
uint mod3Value = byteSum.Mod3();
|
mod5 = accumulator;
|
||||||
|
|
||||||
mod10 = (mod8 & 1UL) == 0UL
|
mod10 = (mod8 & 1UL) == 0UL
|
||||||
? mod5Value switch
|
? accumulator switch
|
||||||
{
|
{
|
||||||
0U => 0UL,
|
0U => 0UL,
|
||||||
1U => 6UL,
|
1U => 6UL,
|
||||||
@@ -88,7 +91,7 @@ public static class ULongExtensions
|
|||||||
3U => 8UL,
|
3U => 8UL,
|
||||||
_ => 4UL,
|
_ => 4UL,
|
||||||
}
|
}
|
||||||
: mod5Value switch
|
: accumulator switch
|
||||||
{
|
{
|
||||||
0U => 5UL,
|
0U => 5UL,
|
||||||
1U => 1UL,
|
1U => 1UL,
|
||||||
@@ -97,8 +100,9 @@ public static class ULongExtensions
|
|||||||
_ => 9UL,
|
_ => 9UL,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod5 = mod5Value;
|
// Reusing accumulator to hold the mod 3 reduction now that the mod 5 value has been stored.
|
||||||
mod3 = mod3Value;
|
accumulator = byteSum.Mod3();
|
||||||
|
mod3 = accumulator;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -108,12 +112,14 @@ public static class ULongExtensions
|
|||||||
uint mod5Accumulator = 0U;
|
uint mod5Accumulator = 0U;
|
||||||
uint mod7Accumulator = 0U;
|
uint mod7Accumulator = 0U;
|
||||||
uint mod11Accumulator = 0U;
|
uint mod11Accumulator = 0U;
|
||||||
ulong temp = value;
|
ulong temp = 0UL;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
byte current = 0;
|
||||||
|
|
||||||
|
temp = value;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
byte current = (byte)temp;
|
current = (byte)temp;
|
||||||
mod3Accumulator += current;
|
mod3Accumulator += current;
|
||||||
mod5Accumulator += current;
|
mod5Accumulator += current;
|
||||||
mod7Accumulator += (uint)(current * Mod7ByteCoefficients[index]);
|
mod7Accumulator += (uint)(current * Mod7ByteCoefficients[index]);
|
||||||
@@ -124,16 +130,30 @@ public static class ULongExtensions
|
|||||||
}
|
}
|
||||||
while (temp != 0UL);
|
while (temp != 0UL);
|
||||||
|
|
||||||
mod3 = mod3Accumulator.Mod3();
|
// Reusing mod3Accumulator to store the reduced mod 3 remainder before exposing it.
|
||||||
mod5 = mod5Accumulator.Mod5();
|
mod3Accumulator = mod3Accumulator.Mod3();
|
||||||
mod7 = ReduceMod7(mod7Accumulator);
|
// Reusing mod5Accumulator to store the reduced mod 5 remainder before exposing it.
|
||||||
mod11 = ReduceMod11(mod11Accumulator);
|
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)]
|
[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)
|
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();
|
step10 = (mod10 << 1).Mod10();
|
||||||
step8 = ((mod8 << 1) & 7UL);
|
step8 = ((mod8 << 1) & 7UL);
|
||||||
@@ -145,7 +165,7 @@ public static class ULongExtensions
|
|||||||
public static bool IsPrimeCandidate(this ulong n)
|
public static bool IsPrimeCandidate(this ulong n)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
ulong p;
|
ulong p = 0UL;
|
||||||
uint[] smallPrimes = PrimesGenerator.SmallPrimes;
|
uint[] smallPrimes = PrimesGenerator.SmallPrimes;
|
||||||
ulong[] smallPrimesPow2 = PrimesGenerator.SmallPrimesPow2;
|
ulong[] smallPrimesPow2 = PrimesGenerator.SmallPrimesPow2;
|
||||||
int len = smallPrimes.Length;
|
int len = smallPrimes.Length;
|
||||||
@@ -169,11 +189,14 @@ public static class ULongExtensions
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ulong Mod10(this ulong value)
|
public static ulong Mod10(this ulong value)
|
||||||
{
|
{
|
||||||
ulong mod5 = value.Mod5();
|
ulong mod5 = 0UL;
|
||||||
|
ulong result = 0UL;
|
||||||
|
|
||||||
|
mod5 = value.Mod5();
|
||||||
|
|
||||||
if ((value & 1UL) == 0UL)
|
if ((value & 1UL) == 0UL)
|
||||||
{
|
{
|
||||||
return mod5 switch
|
result = mod5 switch
|
||||||
{
|
{
|
||||||
0UL => 0UL,
|
0UL => 0UL,
|
||||||
1UL => 6UL,
|
1UL => 6UL,
|
||||||
@@ -182,8 +205,9 @@ public static class ULongExtensions
|
|||||||
_ => 4UL,
|
_ => 4UL,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return mod5 switch
|
{
|
||||||
|
result = mod5 switch
|
||||||
{
|
{
|
||||||
0UL => 5UL,
|
0UL => 5UL,
|
||||||
1UL => 1UL,
|
1UL => 1UL,
|
||||||
@@ -193,16 +217,26 @@ public static class ULongExtensions
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ulong Mod8(this ulong value) => value & 7UL;
|
public static ulong Mod8(this ulong value) => value & 7UL;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ulong Mod3(this ulong value)
|
public static ulong Mod3(this ulong value)
|
||||||
{
|
{
|
||||||
uint sum = (uint)(value & 0xFFFFUL);
|
uint sum = 0U;
|
||||||
sum += (uint)((value >> 16) & 0xFFFFUL);
|
ulong temp = 0UL;
|
||||||
sum += (uint)((value >> 32) & 0xFFFFUL);
|
|
||||||
sum += (uint)((value >> 48) & 0xFFFFUL);
|
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();
|
return sum.Mod3();
|
||||||
}
|
}
|
||||||
@@ -210,10 +244,17 @@ public static class ULongExtensions
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ulong Mod5(this ulong value)
|
public static ulong Mod5(this ulong value)
|
||||||
{
|
{
|
||||||
uint sum = (uint)(value & 0xFFFFUL);
|
uint sum = 0U;
|
||||||
sum += (uint)((value >> 16) & 0xFFFFUL);
|
ulong temp = 0UL;
|
||||||
sum += (uint)((value >> 32) & 0xFFFFUL);
|
|
||||||
sum += (uint)((value >> 48) & 0xFFFFUL);
|
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();
|
return sum.Mod5();
|
||||||
}
|
}
|
||||||
@@ -227,10 +268,14 @@ public static class ULongExtensions
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ulong Mod7(this ulong value)
|
public static ulong Mod7(this ulong value)
|
||||||
{
|
{
|
||||||
uint low = (uint)value;
|
uint low = 0U;
|
||||||
uint high = (uint)(value >> 32);
|
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)
|
while (remainder >= 7UL)
|
||||||
{
|
{
|
||||||
remainder -= 7UL;
|
remainder -= 7UL;
|
||||||
@@ -242,10 +287,14 @@ public static class ULongExtensions
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ulong Mod11(this ulong value)
|
public static ulong Mod11(this ulong value)
|
||||||
{
|
{
|
||||||
uint low = (uint)value;
|
uint low = 0U;
|
||||||
uint high = (uint)(value >> 32);
|
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)
|
while (remainder >= 11UL)
|
||||||
{
|
{
|
||||||
remainder -= 11UL;
|
remainder -= 11UL;
|
||||||
|
|||||||
Reference in new issue
Block a user