Add shift-first multiply helper and document benchmarks
This commit is contained in:
1 parent
40dff45a81
commit
84ebbed98b
15 files changed
+1333
-100
No files matched your search
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace PerfectNumbers.Core;
|
||||
|
||||
internal static class HeuristicArithmetic
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong MultiplyShiftRight(ulong value, ulong multiplier, int shift)
|
||||
{
|
||||
if (shift < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(shift), "Shift must be non-negative.");
|
||||
}
|
||||
|
||||
UInt128 product = (UInt128)value * multiplier;
|
||||
return (ulong)(product >> shift);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong MultiplyShiftRightShiftFirst(ulong value, ulong multiplier, int shift)
|
||||
{
|
||||
if (shift < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(shift), "Shift must be non-negative.");
|
||||
}
|
||||
|
||||
if (shift == 0)
|
||||
{
|
||||
return MultiplyShiftRight(value, multiplier, 0);
|
||||
}
|
||||
|
||||
if (shift >= 64)
|
||||
{
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
ulong high = value >> shift;
|
||||
ulong mask = (1UL << shift) - 1UL;
|
||||
ulong low = value & mask;
|
||||
|
||||
UInt128 highContribution = (UInt128)high * multiplier;
|
||||
UInt128 lowContribution = (UInt128)low * multiplier;
|
||||
|
||||
UInt128 combined = highContribution + (lowContribution >> shift);
|
||||
return (ulong)combined;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user