I'm hoping this question is ok here. It is in the context of programming, perhaps a bit simple for this audience, and a lot of the discussion here is far beyond me.
I'm trying to calculate modulo 7 using bitshift and addition according to this blog post.
Despite a few errors in that post I was able to get 32 bit versions working for divisors 3, 5, and 15 and with a simple guess I was able to get 64 bit versions working too. The math is a bit over my head and trying to get modulo 7 working has left me fruitless.
Here's the ---working--- not working 32 bit for modulo 7:
static public uint Mersenne7(uint a)
{
a = (a >> 24) + (a & 0xFFFFFF); // sum base 2**24 digits
a = (a >> 12) + (a & 0xFFF); // sum base 2**12 digits
a = (a >> 6) + (a & 0x3F); // sum base 2**6 digits
a = (a >> 3) + (a & 0x7); // sum base 2**2 digits
a = (a >> 2) + (a & 0x7); // sum base 2**2 digits
if (a > 5) a = a - 6;
return a;
}
This is my guess at 64 bit for modulo 7. It also does not work.
static public ulong Mersenne7(ulong a)
{
a = (a >> 48) + (a & 0xFFFFFFFFFFFF); // sum base 2**48 digits
a = (a >> 24) + (a & 0xFFFFFF); // sum base 2**24 digits
a = (a >> 12) + (a & 0xFFF); // sum base 2**12 digits
a = (a >> 6) + (a & 0x3F); // sum base 2**6 digits
a = (a >> 3) + (a & 0x7); // sum base 2**2 digits
a = (a >> 2) + (a & 0x7); // sum base 2**2 digits
if (a > 5) a = a - 6;
return a;
}
For example, here is the working 32 bit version for modulo 15:
static public uint Mersenne15(uint a)
{
a = (a >> 16) + (a & 0xFFFF); // sum base 2**16 digits */
a = (a >> 8) + (a & 0xFF); // sum base 2**8 digits */
a = (a >> 4) + (a & 0xF); // sum base 2**4 digits */
if (a < 15) return a;
if (a < (2 * 15)) return (a - 15);
if (a < (3 * 15)) return (a - (2 * 15));
return (a - (3 * 15));
}
My simple guess for 64 bit worked for modulo 3, 5, and 15 after a little tweaking. There was a pattern to some incorrect results I was getting at first.
static public ulong Mersenne15(ulong a)
{
a = (a >> 32) + (a & 0xFFFFFFFF); // sum base 2**32 digits */
a = (a >> 16) + (a & 0xFFFF); // sum base 2**16 digits */
a = (a >> 8) + (a & 0xFF); // sum base 2**8 digits */
a = (a >> 4) + (a & 0xF); // sum base 2**4 digits */
if (a < 15) return a;
if (a < (2 * 15)) return (a - 15);
if (a < (3 * 15)) return (a - (2 * 15));
if (a < (4 * 15)) return (a - (3 * 15));
return (a - (4 * 15));
}