【发布时间】:2016-02-27 00:22:24
【问题描述】:
欢迎。我正在尝试实施 MillerRabin 测试来检查给定的大数是否是素数。这是我的代码:
public static bool MillerRabinTest(BigInteger number)
{
BigInteger d;
var n = number - 1;
var s = FindK(n, out d);
BigInteger a = 2;
BigInteger y = Calc(a, d, number); //a^d mod number
if (y != BigInteger.One && y != n)
{
for (var r = 1; r <= s - 1; r++)
{
y = Calc(y, 2, number);
if (y == 1)
return false;
}
if (y != n)
return false;
}
return true; //it is probably prime
}
它适用于小型 Biginteger。但是如果我的程序需要计算超过 16 位的数字,程序就会冻结。例如,在成功检查数字是否为素数后,程序突然没有响应。我不明白这怎么可能。如果它检查了一个大数字,那么再次检查另一个应该没有问题。甚至调试器也没有帮助,因为 step options 消失了。如果需要,我可以分享更多功能代码。上面的函数对小数字正常工作。
编辑。更改 BigInteger.ModPow 的模函数有帮助。不幸的是,现在对于更大的数字,超过 3000 位,它永远不会返回质数,这是不可能的。还是真的 prme 数字很难找到?
【问题讨论】:
-
函数返回后是否冻结?还是在活动期间?
-
罪魁祸首,恕我直言,是
Calc(a, d, number),应该是BigInteger.ModPow -
例如。我想要一个 8 位随机数。经过几次尝试,我的程序返回它。如果我想要更大的数字,我根本没有答案。尝试 1 次或多次后会冻结。
-
你至少应该能够弄清楚它冻结在哪一行。
-
@Dago:
ModPow在幼稚的实现中,即Mod(Pow(...))非常效率低下;正确的方式en.wikipedia.org/wiki/Modular_exponentiation
标签: c# biginteger primality-test