-
-
Save qstarin/033c6b4c927a733feecd382648978ca1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.CompilerServices; | |
namespace Common | |
{ | |
static public class Modulo | |
{ | |
static public Func<ulong, ulong> Optimized(ulong divisor) | |
{ | |
switch (divisor) { | |
case 1: return Implementations.Long.One; | |
case 3: return Implementations.Long.Mersenne3; | |
//case 4: Shift/And | |
case 5: return Implementations.Long.Mersenne5; | |
case 6: return Implementations.Long.Mersenne6; | |
case 7: return Implementations.Long.Mersenne7; | |
//case 8: Shift/And | |
case 10: return Implementations.Long.Mersenne10; | |
case 12: return Implementations.Long.Mersenne12; | |
case 14: return Implementations.Long.Mersenne14; | |
case 15: return Implementations.Long.Mersenne15; | |
//case 16: Shift/And | |
case 20: return Implementations.Long.Mersenne20; | |
case 21: return Implementations.Long.Mersenne21; | |
case 24: return Implementations.Long.Mersenne24; | |
case 28: return Implementations.Long.Mersenne28; | |
case 30: return Implementations.Long.Mersenne30; | |
case 31: return Implementations.Long.Mersenne31; | |
//case 32: Shift/And | |
case 35: return Implementations.Long.Mersenne35; | |
case 40: return Implementations.Long.Mersenne40; | |
case 42: return Implementations.Long.Mersenne42; | |
case 48: return Implementations.Long.Mersenne48; | |
case 56: return Implementations.Long.Mersenne56; | |
case 60: return Implementations.Long.Mersenne60; | |
case 62: return Implementations.Long.Mersenne62; | |
case 63: return Implementations.Long.Mersenne63; | |
//case 64: Shift/And | |
case 70: return Implementations.Long.Mersenne70; | |
case 80: return Implementations.Long.Mersenne80; | |
case 84: return Implementations.Long.Mersenne84; | |
case 93: return Implementations.Long.Mersenne93; | |
case 96: return Implementations.Long.Mersenne96; | |
case 105: return Implementations.Long.Mersenne105; | |
case 112: return Implementations.Long.Mersenne112; | |
case 120: return Implementations.Long.Mersenne120; | |
case 124: return Implementations.Long.Mersenne124; | |
case 126: return Implementations.Long.Mersenne126; | |
case 127: return Implementations.Long.Mersenne127; | |
//case 128: Shift/And | |
case 255: return Implementations.Long.Mersenne255; | |
//case 256: Shift/And | |
case 511: return Implementations.Long.Mersenne511; | |
//case 512: Shift/And | |
case 1023: return Implementations.Long.Mersenne1023; | |
//case 1024: Shift/And | |
case 0b10: | |
case 0b100: | |
case 0b1000: | |
case 0b10000: | |
case 0b100000: | |
case 0b1000000: | |
case 0b10000000: | |
case 0b100000000: | |
case 0b1000000000: | |
case 0b10000000000: | |
case 0b100000000000: | |
case 0b1000000000000: | |
case 0b10000000000000: | |
case 0b100000000000000: | |
case 0b1000000000000000: | |
case 0b10000000000000000: | |
case 0b100000000000000000: | |
case 0b1000000000000000000: | |
case 0b10000000000000000000: | |
case 0b100000000000000000000: | |
case 0b1000000000000000000000: | |
case 0b10000000000000000000000: | |
case 0b100000000000000000000000: | |
case 0b1000000000000000000000000: | |
case 0b10000000000000000000000000: | |
case 0b100000000000000000000000000: | |
case 0b1000000000000000000000000000: | |
case 0b10000000000000000000000000000: | |
case 0b100000000000000000000000000000: | |
case 0b1000000000000000000000000000000: | |
case 0b10000000000000000000000000000000: | |
case 0b100000000000000000000000000000000: | |
case 0b1000000000000000000000000000000000: | |
case 0b10000000000000000000000000000000000: | |
case 0b100000000000000000000000000000000000: | |
case 0b1000000000000000000000000000000000000: | |
case 0b10000000000000000000000000000000000000: | |
case 0b100000000000000000000000000000000000000: | |
case 0b1000000000000000000000000000000000000000: | |
case 0b10000000000000000000000000000000000000000: | |
case 0b100000000000000000000000000000000000000000: | |
case 0b1000000000000000000000000000000000000000000: | |
case 0b10000000000000000000000000000000000000000000: | |
case 0b100000000000000000000000000000000000000000000: | |
case 0b1000000000000000000000000000000000000000000000: | |
case 0b10000000000000000000000000000000000000000000000: | |
case 0b100000000000000000000000000000000000000000000000: | |
case 0b1000000000000000000000000000000000000000000000000: | |
case 0b10000000000000000000000000000000000000000000000000: | |
case 0b100000000000000000000000000000000000000000000000000: | |
case 0b1000000000000000000000000000000000000000000000000000: | |
case 0b10000000000000000000000000000000000000000000000000000: | |
case 0b100000000000000000000000000000000000000000000000000000: | |
case 0b1000000000000000000000000000000000000000000000000000000: | |
case 0b10000000000000000000000000000000000000000000000000000000: | |
case 0b100000000000000000000000000000000000000000000000000000000: | |
case 0b1000000000000000000000000000000000000000000000000000000000: | |
case 0b10000000000000000000000000000000000000000000000000000000000: | |
case 0b100000000000000000000000000000000000000000000000000000000000: | |
case 0b1000000000000000000000000000000000000000000000000000000000000: | |
case 0b10000000000000000000000000000000000000000000000000000000000000: | |
case 0b100000000000000000000000000000000000000000000000000000000000000: | |
case 0b1000000000000000000000000000000000000000000000000000000000000000: | |
return n => Implementations.Long.ShiftAnd(n, divisor); | |
default: return n => Implementations.Long.ModuloOperator(n, divisor); | |
} | |
} | |
static public class Implementations | |
{ | |
static public class Long | |
{ | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong One(ulong dividend) => 0; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong ModuloOperator(ulong dividend, ulong divisor) => (dividend % divisor); | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong ShiftAnd(ulong dividend, ulong divisor) => (dividend & (divisor - 1)); | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne3(ulong dividend) | |
{ | |
dividend = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
dividend = (dividend >> 16) + (dividend & 0xFFFF); | |
dividend = (dividend >> 8) + (dividend & 0xFF); | |
dividend = (dividend >> 4) + (dividend & 0xF); | |
dividend = (dividend >> 2) + (dividend & 0x3); | |
dividend = (dividend >> 2) + (dividend & 0x3); | |
dividend = (dividend >> 2) + (dividend & 0x3); | |
if (dividend > 2) dividend = dividend - 3; | |
return dividend; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne5(ulong dividend) | |
{ | |
dividend = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
dividend = (dividend >> 16) + (dividend & 0xFFFF); | |
dividend = (dividend >> 8) + (dividend & 0xFF); | |
dividend = (dividend >> 4) + (dividend & 0xF); | |
dividend = (dividend >> 4) + (dividend & 0xF); | |
if (dividend > 14) dividend = dividend - 15; // mod 15 | |
if (dividend > 10) dividend = dividend - 10; | |
if (dividend > 4) dividend = dividend - 5; | |
return dividend; | |
} | |
static private readonly ulong[] _mersenne6Table = { 0, 3, 4, 1, 2, 5 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne6(ulong dividend) | |
{ | |
var mod3 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod3 = (mod3 >> 16) + (mod3 & 0xFFFF); | |
mod3 = (mod3 >> 8) + (mod3 & 0xFF); | |
mod3 = (mod3 >> 4) + (mod3 & 0xF); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
if (mod3 > 2) mod3 = mod3 - 3; | |
return _mersenne6Table[(mod3 << 1) | (dividend & 0b1)]; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne7(ulong dividend) | |
{ | |
dividend = (dividend >> 48) + (dividend & 0xFFFFFFFFFFFF); | |
dividend = (dividend >> 24) + (dividend & 0xFFFFFF); | |
dividend = (dividend >> 12) + (dividend & 0xFFF); | |
dividend = (dividend >> 6) + (dividend & 0x3F); | |
dividend = (dividend >> 3) + (dividend & 0x7); | |
dividend = (dividend >> 3) + (dividend & 0x7); | |
if (dividend > 6) dividend = dividend - 7; | |
return dividend; | |
} | |
static private readonly ulong[] _mersenne10Table = { 0, 5, 6, 1, 2, 7, 8, 3, 4, 9 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne10(ulong dividend) | |
{ | |
var mod5 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod5 = (mod5 >> 16) + (mod5 & 0xFFFF); | |
mod5 = (mod5 >> 8) + (mod5 & 0xFF); | |
mod5 = (mod5 >> 4) + (mod5 & 0xF); | |
mod5 = (mod5 >> 4) + (mod5 & 0xF); | |
if (mod5 > 14) mod5 = mod5 - 15; | |
if (mod5 > 9) mod5 = mod5 - 10; | |
if (mod5 > 4) mod5 = mod5 - 5; | |
return _mersenne10Table[(mod5 << 1) | (dividend & 0b1)]; | |
} | |
static private readonly ulong[] _mersenne12Table = { 0, 9, 6, 3, 4, 1, 10, 7, 8, 5, 2, 11 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne12(ulong dividend) | |
{ | |
var mod3 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod3 = (mod3 >> 16) + (mod3 & 0xFFFF); | |
mod3 = (mod3 >> 8) + (mod3 & 0xFF); | |
mod3 = (mod3 >> 4) + (mod3 & 0xF); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
if (mod3 > 2) mod3 = mod3 - 3; | |
return _mersenne12Table[(mod3 << 2) | (dividend & 0b11)]; | |
} | |
static private readonly ulong[] _mersenne14Table = { 0, 7, 8, 1, 2, 9, 10, 3, 4, 11, 12, 5, 6, 13 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne14(ulong dividend) | |
{ | |
var mod7 = (dividend >> 48) + (dividend & 0xFFFFFFFFFFFF); | |
mod7 = (mod7 >> 24) + (mod7 & 0xFFFFFF); | |
mod7 = (mod7 >> 12) + (mod7 & 0xFFF); | |
mod7 = (mod7 >> 6) + (mod7 & 0x3F); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
if (mod7 > 6) mod7 = mod7 - 7; | |
return _mersenne14Table[(mod7 << 1) | (dividend & 0b1)]; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne15(ulong dividend) | |
{ | |
dividend = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
dividend = (dividend >> 16) + (dividend & 0xFFFF); | |
dividend = (dividend >> 8) + (dividend & 0xFF); | |
dividend = (dividend >> 4) + (dividend & 0xF); | |
dividend = (dividend >> 4) + (dividend & 0xF); | |
if (dividend > 14) dividend = dividend - 15; | |
return dividend; | |
} | |
static private readonly ulong[] _mersenne20Table = { 0, 5, 10, 15, 16, 1, 6, 11, 12, 17, 2, 7, 8, 13, 18, 3, 4, 9, 14, 19 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne20(ulong dividend) | |
{ | |
var mod5 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod5 = (mod5 >> 16) + (mod5 & 0xFFFF); | |
mod5 = (mod5 >> 8) + (mod5 & 0xFF); | |
mod5 = (mod5 >> 4) + (mod5 & 0xF); | |
mod5 = (mod5 >> 4) + (mod5 & 0xF); | |
if (mod5 > 14) mod5 = mod5 - 15; | |
if (mod5 > 9) mod5 = mod5 - 10; | |
if (mod5 > 4) mod5 = mod5 - 5; | |
return _mersenne20Table[(mod5 << 2) | (dividend & 0b11)]; | |
} | |
static private readonly ulong[] _mersenne21Table = { 0, 15, 9, 3, 18, 12, 6, 0, 7, 1, 16, 10, 4, 19, 13, 0, 14, 8, 2, 17, 11, 5, 20 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne21(ulong dividend) | |
{ | |
var mod7 = (dividend >> 48) + (dividend & 0xFFFFFFFFFFFF); | |
mod7 = (mod7 >> 24) + (mod7 & 0xFFFFFF); | |
mod7 = (mod7 >> 12) + (mod7 & 0xFFF); | |
mod7 = (mod7 >> 6) + (mod7 & 0x3F); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
if (mod7 > 6) mod7 = mod7 - 7; | |
var mod3 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod3 = (mod3 >> 16) + (mod3 & 0xFFFF); | |
mod3 = (mod3 >> 8) + (mod3 & 0xFF); | |
mod3 = (mod3 >> 4) + (mod3 & 0xF); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
if (mod3 > 2) mod3 = mod3 - 3; | |
return _mersenne21Table[(mod3 << 3) | mod7]; | |
} | |
static private readonly ulong[] _mersenne24Table = { 0, 9, 18, 3, 12, 21, 6, 15, 16, 1, 10, 19, 4, 13, 22, 7, 8, 17, 2, 11, 20, 5, 14, 23 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne24(ulong dividend) | |
{ | |
var mod3 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod3 = (mod3 >> 16) + (mod3 & 0xFFFF); | |
mod3 = (mod3 >> 8) + (mod3 & 0xFF); | |
mod3 = (mod3 >> 4) + (mod3 & 0xF); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
if (mod3 > 2) mod3 = mod3 - 3; | |
return _mersenne24Table[(mod3 << 3) | (dividend & 0b111)]; | |
} | |
static private readonly ulong[] _mersenne28Table = { 0, 21, 14, 7, 8, 1, 22, 15, 16, 9, 2, 23, 24, 17, 10, 3, 4, 25, 18, 11, 12, 5, 26, 19, 20, 13, 6, 27 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne28(ulong dividend) | |
{ | |
var mod7 = (dividend >> 48) + (dividend & 0xFFFFFFFFFFFF); | |
mod7 = (mod7 >> 24) + (mod7 & 0xFFFFFF); | |
mod7 = (mod7 >> 12) + (mod7 & 0xFFF); | |
mod7 = (mod7 >> 6) + (mod7 & 0x3F); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
if (mod7 > 6) mod7 = mod7 - 7; | |
return _mersenne28Table[(mod7 << 2) | (dividend & 0b11)]; | |
} | |
static private readonly ulong[] _mersenne30Table = { 0, 15, 16, 1, 2, 17, 18, 3, 4, 19, 20, 5, 6, 21, 22, 7, 8, 23, 24, 9, 10, 25, 26, 11, 12, 27, 28, 13, 14, 29 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne30(ulong dividend) | |
{ | |
var mod15 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod15 = (mod15 >> 16) + (mod15 & 0xFFFF); | |
mod15 = (mod15 >> 8) + (mod15 & 0xFF); | |
mod15 = (mod15 >> 4) + (mod15 & 0xF); | |
mod15 = (mod15 >> 4) + (mod15 & 0xF); | |
if (mod15 > 14) mod15 = mod15 - 15; | |
return _mersenne30Table[(mod15 << 1) | (dividend & 0b1)]; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne31(ulong dividend) | |
{ | |
dividend = (dividend >> 40) + (dividend & 0xFFFFFFFFFF); | |
dividend = (dividend >> 20) + (dividend & 0xFFFFF); | |
dividend = (dividend >> 10) + (dividend & 0x3FF); | |
dividend = (dividend >> 5) + (dividend & 0x1F); | |
dividend = (dividend >> 5) + (dividend & 0x1F); | |
if (dividend > 30) dividend = dividend - 31; | |
return dividend; | |
} | |
static private readonly ulong[] _mersenne35Table = { 0, 15, 30, 10, 25, 5, 20, 0, 21, 1, 16, 31, 11, 26, 6, 0, 7, 22, 2, 17, 32, 12, 27, 0, 28, 8, 23, 3, 18, 33, 13, 0, 14, 29, 9, 24, 4, 19, 34 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne35(ulong dividend) | |
{ | |
var mod7 = (dividend >> 48) + (dividend & 0xFFFFFFFFFFFF); | |
mod7 = (mod7 >> 24) + (mod7 & 0xFFFFFF); | |
mod7 = (mod7 >> 12) + (mod7 & 0xFFF); | |
mod7 = (mod7 >> 6) + (mod7 & 0x3F); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
if (mod7 > 6) mod7 = mod7 - 7; | |
var mod5 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod5 = (mod5 >> 16) + (mod5 & 0xFFFF); | |
mod5 = (mod5 >> 8) + (mod5 & 0xFF); | |
mod5 = (mod5 >> 4) + (mod5 & 0xF); | |
mod5 = (mod5 >> 4) + (mod5 & 0xF); | |
if (mod5 > 14) mod5 = mod5 - 15; | |
if (mod5 > 9) mod5 = mod5 - 10; | |
if (mod5 > 4) mod5 = mod5 - 5; | |
return _mersenne35Table[(mod5 << 3) | mod7]; | |
} | |
static private readonly ulong[] _mersenne40Table = { 0, 25, 10, 35, 20, 5, 30, 15, 16, 1, 26, 11, 36, 21, 6, 31, 32, 17, 2, 27, 12, 37, 22, 7, 8, 33, 18, 3, 28, 13, 38, 23, 24, 9, 34, 19, 4, 29, 14, 39 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne40(ulong dividend) | |
{ | |
var mod5 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod5 = (mod5 >> 16) + (mod5 & 0xFFFF); | |
mod5 = (mod5 >> 8) + (mod5 & 0xFF); | |
mod5 = (mod5 >> 4) + (mod5 & 0xF); | |
mod5 = (mod5 >> 4) + (mod5 & 0xF); | |
if (mod5 > 14) mod5 = mod5 - 15; | |
if (mod5 > 9) mod5 = mod5 - 10; | |
if (mod5 > 4) mod5 = mod5 - 5; | |
return _mersenne40Table[(mod5 << 3) | (dividend & 0b111)]; | |
} | |
static private readonly ulong[] _mersenne42Table = { 0, 21, 28, 7, 14, 35, 0, 0, 36, 15, 22, 1, 8, 29, 0, 0, 30, 9, 16, 37, 2, 23, 0, 0, 24, 3, 10, 31, 38, 17, 0, 0, 18, 39, 4, 25, 32, 11, 0, 0, 12, 33, 40, 19, 26, 5, 0, 0, 6, 27, 34, 13, 20, 41 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne42(ulong dividend) | |
{ | |
var mod7 = (dividend >> 48) + (dividend & 0xFFFFFFFFFFFF); | |
mod7 = (mod7 >> 24) + (mod7 & 0xFFFFFF); | |
mod7 = (mod7 >> 12) + (mod7 & 0xFFF); | |
mod7 = (mod7 >> 6) + (mod7 & 0x3F); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
if (mod7 > 6) mod7 = mod7 - 7; | |
var mod3 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod3 = (mod3 >> 16) + (mod3 & 0xFFFF); | |
mod3 = (mod3 >> 8) + (mod3 & 0xFF); | |
mod3 = (mod3 >> 4) + (mod3 & 0xF); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
if (mod3 > 2) mod3 = mod3 - 3; | |
return _mersenne42Table[(mod7 << 3) | (mod3 << 1) | (dividend & 0b1)]; | |
} | |
static private readonly ulong[] _mersenne48Table = { 0, 33, 18, 3, 36, 21, 6, 39, 24, 9, 42, 27, 12, 45, 30, 15, 16, 1, 34, 19, 4, 37, 22, 7, 40, 25, 10, 43, 28, 13, 46, 31, 32, 17, 2, 35, 20, 5, 38, 23, 8, 41, 26, 11, 44, 29, 14, 47 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne48(ulong dividend) | |
{ | |
var mod3 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod3 = (mod3 >> 16) + (mod3 & 0xFFFF); | |
mod3 = (mod3 >> 8) + (mod3 & 0xFF); | |
mod3 = (mod3 >> 4) + (mod3 & 0xF); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
if (mod3 > 2) mod3 = mod3 - 3; | |
return _mersenne48Table[(mod3 << 4) | (dividend & 0b1111)]; | |
} | |
static private readonly ulong[] _mersenne56Table = { 0, 49, 42, 35, 28, 21, 14, 7, 8, 1, 50, 43, 36, 29, 22, 15, 16, 9, 2, 51, 44, 37, 30, 23, 24, 17, 10, 3, 52, 45, 38, 31, 32, 25, 18, 11, 4, 53, 46, 39, 40, 33, 26, 19, 12, 5, 54, 47, 48, 41, 34, 27, 20, 13, 6, 55 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne56(ulong dividend) | |
{ | |
var mod7 = (dividend >> 48) + (dividend & 0xFFFFFFFFFFFF); | |
mod7 = (mod7 >> 24) + (mod7 & 0xFFFFFF); | |
mod7 = (mod7 >> 12) + (mod7 & 0xFFF); | |
mod7 = (mod7 >> 6) + (mod7 & 0x3F); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
if (mod7 > 6) mod7 = mod7 - 7; | |
return _mersenne56Table[(mod7 << 3) | (dividend & 0b111)]; | |
} | |
static private readonly ulong[] _mersenne60Table = { 0, 45, 30, 15, 16, 1, 46, 31, 32, 17, 2, 47, 48, 33, 18, 3, 4, 49, 34, 19, 20, 5, 50, 35, 36, 21, 6, 51, 52, 37, 22, 7, 8, 53, 38, 23, 24, 9, 54, 39, 40, 25, 10, 55, 56, 41, 26, 11, 12, 57, 42, 27, 28, 13, 58, 43, 44, 29, 14, 59 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne60(ulong dividend) | |
{ | |
var mod15 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod15 = (mod15 >> 16) + (mod15 & 0xFFFF); | |
mod15 = (mod15 >> 8) + (mod15 & 0xFF); | |
mod15 = (mod15 >> 4) + (mod15 & 0xF); | |
mod15 = (mod15 >> 4) + (mod15 & 0xF); | |
if (mod15 > 14) mod15 = mod15 - 15; | |
return _mersenne60Table[(mod15 << 2) | (dividend & 0b11)]; | |
} | |
static private readonly ulong[] _mersenne62Table = { 0, 31, 32, 1, 2, 33, 34, 3, 4, 35, 36, 5, 6, 37, 38, 7, 8, 39, 40, 9, 10, 41, 42, 11, 12, 43, 44, 13, 14, 45, 46, 15, 16, 47, 48, 17, 18, 49, 50, 19, 20, 51, 52, 21, 22, 53, 54, 23, 24, 55, 56, 25, 26, 57, 58, 27, 28, 59, 60, 29, 30, 61 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne62(ulong dividend) | |
{ | |
var mod31 = (dividend >> 40) + (dividend & 0xFFFFFFFFFF); | |
mod31 = (mod31 >> 20) + (mod31 & 0xFFFFF); | |
mod31 = (mod31 >> 10) + (mod31 & 0x3FF); | |
mod31 = (mod31 >> 5) + (mod31 & 0x1F); | |
mod31 = (mod31 >> 5) + (mod31 & 0x1F); | |
if (mod31 > 30) mod31 = mod31 - 31; | |
return _mersenne62Table[(mod31 << 1) | (dividend & 0b1)]; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne63(ulong dividend) | |
{ | |
dividend = (dividend >> 48) + (dividend & 0xFFFFFFFFFFFF); | |
dividend = (dividend >> 24) + (dividend & 0xFFFFFF); | |
dividend = (dividend >> 12) + (dividend & 0xFFF); | |
dividend = (dividend >> 6) + (dividend & 0x3F); | |
dividend = (dividend >> 6) + (dividend & 0x3F); | |
if (dividend > 62) dividend = dividend - 63; | |
return dividend; | |
} | |
static private readonly ulong[] _mersenne70Table = { 0, 35, 50, 15, 30, 65, 10, 45, 60, 25, 40, 5, 20, 55, 0, 0, 56, 21, 36, 1, 16, 51, 66, 31, 46, 11, 26, 61, 6, 41, 0, 0, 42, 7, 22, 57, 2, 37, 52, 17, 32, 67, 12, 47, 62, 27, 0, 0, 28, 63, 8, 43, 58, 23, 38, 3, 18, 53, 68, 33, 48, 13, 0, 0, 14, 49, 64, 29, 44, 9, 24, 59, 4, 39, 54, 19, 34, 69 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne70(ulong dividend) | |
{ | |
var mod7 = (dividend >> 48) + (dividend & 0xFFFFFFFFFFFF); | |
mod7 = (mod7 >> 24) + (mod7 & 0xFFFFFF); | |
mod7 = (mod7 >> 12) + (mod7 & 0xFFF); | |
mod7 = (mod7 >> 6) + (mod7 & 0x3F); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
if (mod7 > 6) mod7 = mod7 - 7; | |
var mod5 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod5 = (mod5 >> 16) + (mod5 & 0xFFFF); | |
mod5 = (mod5 >> 8) + (mod5 & 0xFF); | |
mod5 = (mod5 >> 4) + (mod5 & 0xF); | |
mod5 = (mod5 >> 4) + (mod5 & 0xF); | |
if (mod5 > 14) mod5 = mod5 - 15; | |
if (mod5 > 9) mod5 = mod5 - 10; | |
if (mod5 > 4) mod5 = mod5 - 5; | |
return _mersenne70Table[(mod5 << 4) | (mod7 << 1) | (dividend & 0b1)]; | |
} | |
static private readonly ulong[] _mersenne80Table = { 0, 65, 50, 35, 20, 5, 70, 55, 40, 25, 10, 75, 60, 45, 30, 15, 16, 1, 66, 51, 36, 21, 6, 71, 56, 41, 26, 11, 76, 61, 46, 31, 32, 17, 2, 67, 52, 37, 22, 7, 72, 57, 42, 27, 12, 77, 62, 47, 48, 33, 18, 3, 68, 53, 38, 23, 8, 73, 58, 43, 28, 13, 78, 63, 64, 49, 34, 19, 4, 69, 54, 39, 24, 9, 74, 59, 44, 29, 14, 79 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne80(ulong dividend) | |
{ | |
var mod5 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod5 = (mod5 >> 16) + (mod5 & 0xFFFF); | |
mod5 = (mod5 >> 8) + (mod5 & 0xFF); | |
mod5 = (mod5 >> 4) + (mod5 & 0xF); | |
mod5 = (mod5 >> 4) + (mod5 & 0xF); | |
if (mod5 > 14) mod5 = mod5 - 15; | |
if (mod5 > 9) mod5 = mod5 - 10; | |
if (mod5 > 4) mod5 = mod5 - 5; | |
return _mersenne80Table[(mod5 << 4) | (dividend & 0b1111)]; | |
} | |
static private readonly ulong[] _mersenne84Table = { 0, 21, 42, 63, 28, 49, 70, 7, 56, 77, 14, 35, 0, 0, 0, 0, 36, 57, 78, 15, 64, 1, 22, 43, 8, 29, 50, 71, 0, 0, 0, 0, 72, 9, 30, 51, 16, 37, 58, 79, 44, 65, 2, 23, 0, 0, 0, 0, 24, 45, 66, 3, 52, 73, 10, 31, 80, 17, 38, 59, 0, 0, 0, 0, 60, 81, 18, 39, 4, 25, 46, 67, 32, 53, 74, 11, 0, 0, 0, 0, 12, 33, 54, 75, 40, 61, 82, 19, 68, 5, 26, 47, 0, 0, 0, 0, 48, 69, 6, 27, 76, 13, 34, 55, 20, 41, 62, 83 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne84(ulong dividend) | |
{ | |
var mod7 = (dividend >> 48) + (dividend & 0xFFFFFFFFFFFF); | |
mod7 = (mod7 >> 24) + (mod7 & 0xFFFFFF); | |
mod7 = (mod7 >> 12) + (mod7 & 0xFFF); | |
mod7 = (mod7 >> 6) + (mod7 & 0x3F); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
if (mod7 > 6) mod7 = mod7 - 7; | |
var mod3 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod3 = (mod3 >> 16) + (mod3 & 0xFFFF); | |
mod3 = (mod3 >> 8) + (mod3 & 0xFF); | |
mod3 = (mod3 >> 4) + (mod3 & 0xF); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
if (mod3 > 2) mod3 = mod3 - 3; | |
return _mersenne84Table[(mod7 << 4) | (mod3 << 2) | (dividend & 0b11)]; | |
} | |
static private readonly ulong[] _mersenne93Table = { 0, 31, 62, 0, 63, 1, 32, 0, 33, 64, 2, 0, 3, 34, 65, 0, 66, 4, 35, 0, 36, 67, 5, 0, 6, 37, 68, 0, 69, 7, 38, 0, 39, 70, 8, 0, 9, 40, 71, 0, 72, 10, 41, 0, 42, 73, 11, 0, 12, 43, 74, 0, 75, 13, 44, 0, 45, 76, 14, 0, 15, 46, 77, 0, 78, 16, 47, 0, 48, 79, 17, 0, 18, 49, 80, 0, 81, 19, 50, 0, 51, 82, 20, 0, 21, 52, 83, 0, 84, 22, 53, 0, 54, 85, 23, 0, 24, 55, 86, 0, 87, 25, 56, 0, 57, 88, 26, 0, 27, 58, 89, 0, 90, 28, 59, 0, 60, 91, 29, 0, 30, 61, 92 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne93(ulong dividend) | |
{ | |
var mod3 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod3 = (mod3 >> 16) + (mod3 & 0xFFFF); | |
mod3 = (mod3 >> 8) + (mod3 & 0xFF); | |
mod3 = (mod3 >> 4) + (mod3 & 0xF); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
if (mod3 > 2) mod3 = mod3 - 3; | |
var mod31 = (dividend >> 40) + (dividend & 0xFFFFFFFFFF); | |
mod31 = (mod31 >> 20) + (mod31 & 0xFFFFF); | |
mod31 = (mod31 >> 10) + (mod31 & 0x3FF); | |
mod31 = (mod31 >> 5) + (mod31 & 0x1F); | |
mod31 = (mod31 >> 5) + (mod31 & 0x1F); | |
if (mod31 > 30) mod31 = mod31 - 31; | |
return _mersenne93Table[(mod31 << 2) | mod3]; | |
} | |
static private readonly ulong[] _mersenne96Table = { 0, 33, 66, 3, 36, 69, 6, 39, 72, 9, 42, 75, 12, 45, 78, 15, 48, 81, 18, 51, 84, 21, 54, 87, 24, 57, 90, 27, 60, 93, 30, 63, 64, 1, 34, 67, 4, 37, 70, 7, 40, 73, 10, 43, 76, 13, 46, 79, 16, 49, 82, 19, 52, 85, 22, 55, 88, 25, 58, 91, 28, 61, 94, 31, 32, 65, 2, 35, 68, 5, 38, 71, 8, 41, 74, 11, 44, 77, 14, 47, 80, 17, 50, 83, 20, 53, 86, 23, 56, 89, 26, 59, 92, 29, 62, 95 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne96(ulong dividend) | |
{ | |
var mod3 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod3 = (mod3 >> 16) + (mod3 & 0xFFFF); | |
mod3 = (mod3 >> 8) + (mod3 & 0xFF); | |
mod3 = (mod3 >> 4) + (mod3 & 0xF); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
mod3 = (mod3 >> 2) + (mod3 & 0x3); | |
if (mod3 > 2) mod3 = mod3 - 3; | |
return _mersenne96Table[(mod3 << 5) | (dividend & 0b11111)]; | |
} | |
static private readonly ulong[] _mersenne105Table = { 0, 15, 30, 45, 60, 75, 90, 0, 91, 1, 16, 31, 46, 61, 76, 0, 77, 92, 2, 17, 32, 47, 62, 0, 63, 78, 93, 3, 18, 33, 48, 0, 49, 64, 79, 94, 4, 19, 34, 0, 35, 50, 65, 80, 95, 5, 20, 0, 21, 36, 51, 66, 81, 96, 6, 0, 7, 22, 37, 52, 67, 82, 97, 0, 98, 8, 23, 38, 53, 68, 83, 0, 84, 99, 9, 24, 39, 54, 69, 0, 70, 85, 100, 10, 25, 40, 55, 0, 56, 71, 86, 101, 11, 26, 41, 0, 42, 57, 72, 87, 102, 12, 27, 0, 28, 43, 58, 73, 88, 103, 13, 0, 14, 29, 44, 59, 74, 89, 104 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne105(ulong dividend) | |
{ | |
var mod7 = (dividend >> 48) + (dividend & 0xFFFFFFFFFFFF); | |
mod7 = (mod7 >> 24) + (mod7 & 0xFFFFFF); | |
mod7 = (mod7 >> 12) + (mod7 & 0xFFF); | |
mod7 = (mod7 >> 6) + (mod7 & 0x3F); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
if (mod7 > 6) mod7 = mod7 - 7; | |
var mod15 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod15 = (mod15 >> 16) + (mod15 & 0xFFFF); | |
mod15 = (mod15 >> 8) + (mod15 & 0xFF); | |
mod15 = (mod15 >> 4) + (mod15 & 0xF); | |
mod15 = (mod15 >> 4) + (mod15 & 0xF); | |
if (mod15 > 14) mod15 = mod15 - 15; | |
return _mersenne105Table[(mod15 << 3) | mod7]; | |
} | |
static private readonly ulong[] _mersenne112Table = { 0, 49, 98, 35, 84, 21, 70, 7, 56, 105, 42, 91, 28, 77, 14, 63, 64, 1, 50, 99, 36, 85, 22, 71, 8, 57, 106, 43, 92, 29, 78, 15, 16, 65, 2, 51, 100, 37, 86, 23, 72, 9, 58, 107, 44, 93, 30, 79, 80, 17, 66, 3, 52, 101, 38, 87, 24, 73, 10, 59, 108, 45, 94, 31, 32, 81, 18, 67, 4, 53, 102, 39, 88, 25, 74, 11, 60, 109, 46, 95, 96, 33, 82, 19, 68, 5, 54, 103, 40, 89, 26, 75, 12, 61, 110, 47, 48, 97, 34, 83, 20, 69, 6, 55, 104, 41, 90, 27, 76, 13, 62, 111 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne112(ulong dividend) | |
{ | |
var mod7 = (dividend >> 48) + (dividend & 0xFFFFFFFFFFFF); | |
mod7 = (mod7 >> 24) + (mod7 & 0xFFFFFF); | |
mod7 = (mod7 >> 12) + (mod7 & 0xFFF); | |
mod7 = (mod7 >> 6) + (mod7 & 0x3F); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
mod7 = (mod7 >> 3) + (mod7 & 0x7); | |
if (mod7 > 6) mod7 = mod7 - 7; | |
return _mersenne112Table[(mod7 << 4) | (dividend & 0b1111)]; | |
} | |
static private readonly ulong[] _mersenne120Table = { 0, 105, 90, 75, 60, 45, 30, 15, 16, 1, 106, 91, 76, 61, 46, 31, 32, 17, 2, 107, 92, 77, 62, 47, 48, 33, 18, 3, 108, 93, 78, 63, 64, 49, 34, 19, 4, 109, 94, 79, 80, 65, 50, 35, 20, 5, 110, 95, 96, 81, 66, 51, 36, 21, 6, 111, 112, 97, 82, 67, 52, 37, 22, 7, 8, 113, 98, 83, 68, 53, 38, 23, 24, 9, 114, 99, 84, 69, 54, 39, 40, 25, 10, 115, 100, 85, 70, 55, 56, 41, 26, 11, 116, 101, 86, 71, 72, 57, 42, 27, 12, 117, 102, 87, 88, 73, 58, 43, 28, 13, 118, 103, 104, 89, 74, 59, 44, 29, 14, 119 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne120(ulong dividend) | |
{ | |
var mod15 = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
mod15 = (mod15 >> 16) + (mod15 & 0xFFFF); | |
mod15 = (mod15 >> 8) + (mod15 & 0xFF); | |
mod15 = (mod15 >> 4) + (mod15 & 0xF); | |
mod15 = (mod15 >> 4) + (mod15 & 0xF); | |
if (mod15 > 14) mod15 = mod15 - 15; | |
return _mersenne120Table[(mod15 << 3) | (dividend & 0b111)]; | |
} | |
static private readonly ulong[] _mersenne124Table = { 0, 93, 62, 31, 32, 1, 94, 63, 64, 33, 2, 95, 96, 65, 34, 3, 4, 97, 66, 35, 36, 5, 98, 67, 68, 37, 6, 99, 100, 69, 38, 7, 8, 101, 70, 39, 40, 9, 102, 71, 72, 41, 10, 103, 104, 73, 42, 11, 12, 105, 74, 43, 44, 13, 106, 75, 76, 45, 14, 107, 108, 77, 46, 15, 16, 109, 78, 47, 48, 17, 110, 79, 80, 49, 18, 111, 112, 81, 50, 19, 20, 113, 82, 51, 52, 21, 114, 83, 84, 53, 22, 115, 116, 85, 54, 23, 24, 117, 86, 55, 56, 25, 118, 87, 88, 57, 26, 119, 120, 89, 58, 27, 28, 121, 90, 59, 60, 29, 122, 91, 92, 61, 30, 123 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne124(ulong dividend) | |
{ | |
var mod31 = (dividend >> 40) + (dividend & 0xFFFFFFFFFF); | |
mod31 = (mod31 >> 20) + (mod31 & 0xFFFFF); | |
mod31 = (mod31 >> 10) + (mod31 & 0x3FF); | |
mod31 = (mod31 >> 5) + (mod31 & 0x1F); | |
mod31 = (mod31 >> 5) + (mod31 & 0x1F); | |
if (mod31 > 30) mod31 = mod31 - 31; | |
return _mersenne124Table[(mod31 << 2) | (dividend & 0b11)]; | |
} | |
static private readonly ulong[] _mersenne126Table = { 0, 63, 64, 1, 2, 65, 66, 3, 4, 67, 68, 5, 6, 69, 70, 7, 8, 71, 72, 9, 10, 73, 74, 11, 12, 75, 76, 13, 14, 77, 78, 15, 16, 79, 80, 17, 18, 81, 82, 19, 20, 83, 84, 21, 22, 85, 86, 23, 24, 87, 88, 25, 26, 89, 90, 27, 28, 91, 92, 29, 30, 93, 94, 31, 32, 95, 96, 33, 34, 97, 98, 35, 36, 99, 100, 37, 38, 101, 102, 39, 40, 103, 104, 41, 42, 105, 106, 43, 44, 107, 108, 45, 46, 109, 110, 47, 48, 111, 112, 49, 50, 113, 114, 51, 52, 115, 116, 53, 54, 117, 118, 55, 56, 119, 120, 57, 58, 121, 122, 59, 60, 123, 124, 61, 62, 125 }; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne126(ulong dividend) | |
{ | |
var mod63 = (dividend >> 48) + (dividend & 0xFFFFFFFFFFFF); | |
mod63 = (mod63 >> 24) + (mod63 & 0xFFFFFF); | |
mod63 = (mod63 >> 12) + (mod63 & 0xFFF); | |
mod63 = (mod63 >> 6) + (mod63 & 0x3F); | |
mod63 = (mod63 >> 6) + (mod63 & 0x3F); | |
if (mod63 > 62) mod63 = mod63 - 63; | |
return _mersenne126Table[(mod63 << 1) | (dividend & 0b1)]; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne127(ulong dividend) | |
{ | |
dividend = (dividend >> 56) + (dividend & 0xFFFFFFFFFFFFFF); | |
dividend = (dividend >> 28) + (dividend & 0xFFFFFFF); | |
dividend = (dividend >> 14) + (dividend & 0x3FFF); | |
dividend = (dividend >> 7) + (dividend & 0x7F); | |
dividend = (dividend >> 7) + (dividend & 0x7F); | |
if (dividend > 126) dividend = dividend - 127; | |
return dividend; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne255(ulong dividend) | |
{ | |
dividend = (dividend >> 32) + (dividend & 0xFFFFFFFF); | |
dividend = (dividend >> 16) + (dividend & 0xFFFF); | |
dividend = (dividend >> 8) + (dividend & 0xFF); | |
dividend = (dividend >> 8) + (dividend & 0xFF); | |
if (dividend > 254) dividend = dividend - 255; | |
return dividend; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne511(ulong dividend) | |
{ | |
dividend = (dividend >> 36) + (dividend & 0xFFFFFFFFF); | |
dividend = (dividend >> 18) + (dividend & 0x3FFFF); | |
dividend = (dividend >> 9) + (dividend & 0x1FF); | |
dividend = (dividend >> 9) + (dividend & 0x1FF); | |
if (dividend > 510) dividend = dividend - 511; | |
return dividend; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
static public ulong Mersenne1023(ulong dividend) | |
{ | |
dividend = (dividend >> 40) + (dividend & 0xFFFFFFFFFF); | |
dividend = (dividend >> 20) + (dividend & 0xFFFFF); | |
dividend = (dividend >> 10) + (dividend & 0x3FF); | |
dividend = (dividend >> 10) + (dividend & 0x3FF); | |
if (dividend > 1022) dividend = dividend - 1023; | |
return dividend; | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using NUnit.Framework; | |
namespace Common.Tests | |
{ | |
[TestFixture] | |
public class OptimizedModulo_Tests | |
{ | |
[TestCase((ulong)0)] | |
[TestCase((ulong)1)] | |
[TestCase((ulong)2)] | |
[TestCase((ulong)3)] | |
[TestCase((ulong)4)] | |
[TestCase((ulong)5)] | |
[TestCase((ulong)6)] | |
[TestCase((ulong)7)] | |
[TestCase((ulong)8)] | |
[TestCase((ulong)9)] | |
[TestCase((ulong)10)] | |
[TestCase((ulong)11)] | |
[TestCase((ulong)12)] | |
[TestCase((ulong)13)] | |
[TestCase((ulong)14)] | |
[TestCase((ulong)15)] | |
[TestCase((ulong)16)] | |
[TestCase((ulong)17)] | |
[TestCase((ulong)18)] | |
[TestCase((ulong)19)] | |
[TestCase((ulong)20)] | |
[TestCase((ulong)21)] | |
[TestCase((ulong)22)] | |
[TestCase((ulong)23)] | |
[TestCase((ulong)24)] | |
[TestCase((ulong)25)] | |
[TestCase((ulong)26)] | |
[TestCase((ulong)27)] | |
[TestCase((ulong)28)] | |
[TestCase((ulong)29)] | |
[TestCase((ulong)30)] | |
[TestCase((ulong)31)] | |
[TestCase((ulong)32)] | |
[TestCase((ulong)9846)] | |
[TestCase((ulong)7235810)] | |
[TestCase((ulong)7235811)] | |
[TestCase((ulong)7235812)] | |
[TestCase((ulong)7235813)] | |
[TestCase((ulong)7235814)] | |
[TestCase((ulong)7235815)] | |
[TestCase((ulong)7235816)] | |
[TestCase((ulong)7235817)] | |
[TestCase((ulong)7235818)] | |
[TestCase((ulong)7235819)] | |
[TestCase((ulong)7235820)] | |
[TestCase((ulong)1658656460)] | |
[TestCase((ulong)1658656461)] | |
[TestCase((ulong)1658656462)] | |
[TestCase((ulong)1658656463)] | |
[TestCase((ulong)1658656464)] | |
[TestCase((ulong)1658656465)] | |
[TestCase((ulong)1658656466)] | |
[TestCase((ulong)1658656467)] | |
[TestCase((ulong)1658656468)] | |
[TestCase((ulong)1658656469)] | |
[TestCase((ulong)1658656470)] | |
[TestCase((ulong)1658656471)] | |
[TestCase((ulong)1658656472)] | |
[TestCase((ulong)1658656473)] | |
[TestCase((ulong)1658656474)] | |
[TestCase((ulong)1658656475)] | |
[TestCase((ulong)1658656476)] | |
[TestCase((ulong)1658656477)] | |
[TestCase((ulong)1658656478)] | |
[TestCase((ulong)1658656479)] | |
[TestCase((ulong)1658656480)] | |
[TestCase((ulong)2147483630)] | |
[TestCase((ulong)2147483631)] | |
[TestCase((ulong)2147483632)] | |
[TestCase((ulong)2147483633)] | |
[TestCase((ulong)2147483634)] | |
[TestCase((ulong)2147483635)] | |
[TestCase((ulong)2147483636)] | |
[TestCase((ulong)2147483637)] | |
[TestCase((ulong)2147483638)] | |
[TestCase((ulong)2147483639)] | |
[TestCase((ulong)2147483640)] | |
[TestCase((ulong)2147483641)] | |
[TestCase((ulong)2147483642)] | |
[TestCase((ulong)2147483643)] | |
[TestCase((ulong)2147483644)] | |
[TestCase((ulong)2147483645)] | |
[TestCase((ulong)2147483646)] | |
[TestCase((ulong)int.MaxValue)] | |
[TestCase((ulong)4294967280)] | |
[TestCase((ulong)4294967281)] | |
[TestCase((ulong)4294967282)] | |
[TestCase((ulong)4294967283)] | |
[TestCase((ulong)4294967284)] | |
[TestCase((ulong)4294967285)] | |
[TestCase((ulong)4294967286)] | |
[TestCase((ulong)4294967287)] | |
[TestCase((ulong)4294967288)] | |
[TestCase((ulong)4294967289)] | |
[TestCase((ulong)4294967290)] | |
[TestCase((ulong)4294967291)] | |
[TestCase((ulong)4294967292)] | |
[TestCase((ulong)4294967293)] | |
[TestCase((ulong)4294967294)] | |
[TestCase((ulong)4294967295)] | |
[TestCase((ulong)uint.MaxValue)] | |
[TestCase((ulong)71111111235810L)] | |
[TestCase((ulong)71111111235811L)] | |
[TestCase((ulong)71111111235812L)] | |
[TestCase((ulong)71111111235813L)] | |
[TestCase((ulong)71111111235814L)] | |
[TestCase((ulong)71111111235815L)] | |
[TestCase((ulong)71111111235816L)] | |
[TestCase((ulong)71111111235817L)] | |
[TestCase((ulong)71111111235818L)] | |
[TestCase((ulong)71111111235819L)] | |
[TestCase((ulong)71111111235820L)] | |
[TestCase((ulong)1658655656565656460L)] | |
[TestCase((ulong)1658655656565656461L)] | |
[TestCase((ulong)1658655656565656462L)] | |
[TestCase((ulong)1658655656565656463L)] | |
[TestCase((ulong)1658655656565656464L)] | |
[TestCase((ulong)1658655656565656465L)] | |
[TestCase((ulong)1658655656565656466L)] | |
[TestCase((ulong)1658655656565656467L)] | |
[TestCase((ulong)1658655656565656468L)] | |
[TestCase((ulong)1658655656565656469L)] | |
[TestCase((ulong)1658655656565656470L)] | |
[TestCase((ulong)21474444444483630L)] | |
[TestCase((ulong)214744444444483631L)] | |
[TestCase((ulong)214744444444483632L)] | |
[TestCase((ulong)214744444444483633L)] | |
[TestCase((ulong)214744444444483634L)] | |
[TestCase((ulong)214744444444483635L)] | |
[TestCase((ulong)214744444444483636L)] | |
[TestCase((ulong)214744444444483637L)] | |
[TestCase((ulong)214744444444483638L)] | |
[TestCase((ulong)214744444444483639L)] | |
[TestCase((ulong)214744444444483640L)] | |
[TestCase((ulong)9223372036854775790L)] | |
[TestCase((ulong)9223372036854775791L)] | |
[TestCase((ulong)9223372036854775792L)] | |
[TestCase((ulong)9223372036854775793L)] | |
[TestCase((ulong)9223372036854775794L)] | |
[TestCase((ulong)9223372036854775795L)] | |
[TestCase((ulong)9223372036854775796L)] | |
[TestCase((ulong)9223372036854775797L)] | |
[TestCase((ulong)9223372036854775798L)] | |
[TestCase((ulong)9223372036854775799L)] | |
[TestCase((ulong)9223372036854775800L)] | |
[TestCase((ulong)9223372036854775801L)] | |
[TestCase((ulong)9223372036854775802L)] | |
[TestCase((ulong)9223372036854775803L)] | |
[TestCase((ulong)9223372036854775804L)] | |
[TestCase((ulong)9223372036854775805L)] | |
[TestCase((ulong)9223372036854775806L)] | |
[TestCase((ulong)long.MaxValue)] | |
[TestCase((ulong)18446744073709551600L)] | |
[TestCase((ulong)18446744073709551601L)] | |
[TestCase((ulong)18446744073709551602L)] | |
[TestCase((ulong)18446744073709551603L)] | |
[TestCase((ulong)18446744073709551604L)] | |
[TestCase((ulong)18446744073709551605L)] | |
[TestCase((ulong)18446744073709551606L)] | |
[TestCase((ulong)18446744073709551607L)] | |
[TestCase((ulong)18446744073709551608L)] | |
[TestCase((ulong)18446744073709551609L)] | |
[TestCase((ulong)18446744073709551610L)] | |
[TestCase((ulong)18446744073709551611L)] | |
[TestCase((ulong)18446744073709551612L)] | |
[TestCase((ulong)18446744073709551613L)] | |
[TestCase((ulong)18446744073709551614L)] | |
[TestCase((ulong)ulong.MaxValue)] | |
public void Mersenne7(ulong d) | |
{ | |
Assert.AreEqual(d % 7, Modulo.Implementations.Long.Mersenne7(d)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment