【发布时间】:2017-06-08 11:09:44
【问题描述】:
我有一个有效的实现来计算 32 位无符号整数的模 7,但我在 64 位实现上遇到了问题。 32 位实现来自this blog post(修复了一些错误)。我能够获得适用于模 3、5、15 和 6 的 64 位版本,但不适用于 7。数学有点超出我的想象。
供参考,here is a gist with the full code。
这是工作的 32 位:
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;
}
我做了看起来很明显的扩展,它适用于模 3、5 和 15,但对于模 7,结果到处都是,没有明显的模式(除了结果都在 7 以下):
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;
}
64 位的相同技术显然不适用于 mod 7。我一直在尝试一些变体,但没有得到明显更好的效果,而且我不确定如何系统地完成它。
我已经进行了基准测试,并表明在我的环境中使用 shift 和 add 计算 Mersenne 数的模数比内置的模数运算符更快,并且它在热路径中的紧密循环中运行(静态大小循环缓冲区的索引)。这些较小的除数也比较大的缓冲区更常见。
【问题讨论】:
标签: c# math optimization bit-manipulation modulo