21

我正在尝试解决C#中最大的主要编程实践问题。问题很简单,打印出来或写入文件中的数字:2 57,885,161 - 1(有 17,425,170 位)

我已经设法通过Emil Stevanof .Net 包装器使用令人惊叹的GNU 多精度算术库来解决它

var num = BigInt.Power(2, 57885161) - 1;
File.WriteAllText("biggestPrime.txt", num.ToString());

即使所有当前发布的解决方案都使用这个库,对我来说感觉就像在作弊。有没有办法在托管代码中解决这个问题?想法?建议?

PS:我已经尝试过使用 .Net 4.0 BigInteger但它永远不会结束计算(我等了 5 分钟,但与 GMP 解决方案的 50 秒相比已经很多了)。

4

3 回答 3

7

这也更像是一个骗子而不是一个解决方案,但我使用IntX 库解决了这个问题

IntX.Pow(2, 57885161, MultiplyMode.AutoFht) - 1;

它运行了大约 6 分钟。不过,这仍然不是一个真正的答案。看到“真实”的东西会很有趣。

编辑:使用 C# 秒表我认为计算只需要 5 秒,这是 ToString 的过程需要非常长时间。

于 2013-02-10T12:28:26.650 回答
4

如果您只想使用乘法(和适当的大整数库)来计算这个数字,您可以考虑减少计算的数量。在简单的情况下,您可以在减去 1 之前重复乘以 2(57885161 次),但我们可以用更少的乘法来做到这一点。

考虑重复平方。这给了我们 2, 2 2 , (2 2 ) 2 = 2 4 , (2 4 ) 2 = 2 8等......在平方 25 次之后,我们将计算出 2 (2 25 ) = 2 33554432

如果我们查看 57885161 的二进制表示,我们得到 11011100110100000111101001。即告诉我们我们需要 (for 2 57885161 ) 2 (2 25 ) * 2 (2 24 ) * 2 (2 22 )等...我们可以存储所有需要的在我们计算所需的最高值的过程中 2 的幂,然后只进行最后的乘法运算。这就是 25 + 13 个大整数乘法。然后我们只需要为所需的值减去 1。

于 2013-02-10T12:49:37.663 回答
-5

你要实现的是计算密集型的。Visual C# 和 Visual Basic(以及一般的解释语言)不是为这样的事情而设计的。使用 GMP 是正确的做法,因为它是用纯 C 语言实现的,并且针对执行速度进行了高度优化。

如果您选择仅使用托管代码,请耐心等待:使用 .Net 4.0 BigInteger 可能需要比使用 GMP多 100 倍的时间。要对此进行测试,您应该计算 2 1,000、2 10,000、2 100,000、2 1,000,000和 2 10,000,000并查看使用 .Net 4.0 框架计算每个表达式所需的时间。

如果事实证明所需的时间太长,那么您可以尝试自己进行计算。您应该使用此算法执行求幂,然后从 C++ 移植到 C#我自己的大整数乘法实现或您可能找到的任何其他算法。但是,不能保证您将获得明显更好的性能,因为您仍在使用托管代码。

于 2013-02-10T13:37:07.567 回答