【发布时间】:2011-10-22 16:12:01
【问题描述】:
我用升 C 写了一个米勒拉宾素数测试,但它在每个输入上都返回 false。
代码如下:
static Boolean MilRab(UInt64 n)
{
UInt64[] ar = new UInt64[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };
for (int i = 0; i < 10; i++)
{
if (Tanu(ar[i], n) == true) return false;
}
return true;
}//MilRab
static Boolean Tanu(UInt64 a, UInt64 n)
{
UInt64 b = n - 1;
UInt64 d = 1;
UInt64 x;
Int16 i;
for (i = 63; i >= 0; i--) if (((b >> i) & 1) == 1) break;
for (;i>=0;i--)
{
x = d;
d = ((d * d) % n);
if (d == 1 && x != 1 && x != n - 1) return true;
if (b>>i == 1) d = (d * a) % n;
}
if (d != 1) return true;
return false;
}//Tanu
您认为问题可能是什么?我花了一天的时间进行调试,这让我发疯。谢谢。
【问题讨论】:
-
在
(d * d) % n和(d * a) % n中,乘法可以(并且通常会)在以n为模减少之前将模2^64 包装起来,这是不正确的(对于几乎所有n)。 -
我推荐使用
BigInteger结构体。 -
我使用了 BigInteger.Modpow 和 BigInteger 乘法,它运行良好。谢谢。
-
在 SO 上发布代码时,请尽量保留重要的变量名。
标签: c#