Modulo operators replaced with steppers, where possible.
This commit is contained in:
1 parent
475507ce0c
commit
f7dbc017a9
15 files changed
+531
-151
No files matched your search
@@ -0,0 +1,62 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace PerfectNumbers.Core;
|
||||
|
||||
public struct BidirectionalCycleRemainderStepper(ulong modulus)
|
||||
{
|
||||
private readonly ulong _modulus = modulus;
|
||||
private ulong _previous = 0UL;
|
||||
private ulong _remainder = 0UL;
|
||||
|
||||
public readonly ulong Modulus
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return _modulus;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Initialize(ulong value)
|
||||
{
|
||||
_remainder = value.ReduceCycleRemainder(_modulus);
|
||||
_previous = value;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ulong Step(ulong value)
|
||||
{
|
||||
long delta = unchecked((long)value - (long)_previous);
|
||||
_previous = value;
|
||||
if (delta == 0)
|
||||
{
|
||||
return _remainder;
|
||||
}
|
||||
|
||||
if (delta > 0)
|
||||
{
|
||||
ulong step = ((ulong)delta).ReduceCycleRemainder(_modulus);
|
||||
ulong sum = _remainder + step;
|
||||
if (sum >= _modulus)
|
||||
{
|
||||
sum -= _modulus;
|
||||
}
|
||||
|
||||
_remainder = sum;
|
||||
return _remainder;
|
||||
}
|
||||
|
||||
ulong backward = ((ulong)-delta).ReduceCycleRemainder(_modulus);
|
||||
if (backward > _remainder)
|
||||
{
|
||||
ulong diff = backward - _remainder;
|
||||
ulong wrap = diff.ReduceCycleRemainder(_modulus);
|
||||
_remainder = wrap == 0 ? 0UL : _modulus - wrap;
|
||||
return _remainder;
|
||||
}
|
||||
|
||||
_remainder -= backward;
|
||||
return _remainder;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user