我正在尝试在C#中解决the biggest prime编程实践问题。 问题很简单,打印出来或写入文件号: 2 58,885,161 - 1(其中有17,425,170位数字)
我设法使用惊人的GNU Multiple Precision Arithmetic Library到Emil Stevanof .Net wrapper
解决了这个问题var num = BigInt.Power(2, 57885161) - 1;
File.WriteAllText("biggestPrime.txt", num.ToString());
即使所有当前发布的解决方案都使用此库,对我来说也感觉像是作弊。有没有办法在托管代码中解决这个问题?想法?建议?
PS:我已经尝试过使用.Net 4.0 BigInteger,但从不结束计算(我等了5分钟,但与GMP解决方案的50秒相比已经很多了) )。
答案 0 :(得分:7)
这也是一个骗子而不是解决方案,但我使用IntX library
解决了这个问题IntX.Pow(2, 57885161, MultiplyMode.AutoFht) - 1;
它跑了大约6分钟。尽管如此,这仍然不是一个真正的答案。看到“真实”的东西会很有趣。
编辑:使用C#秒表我认为计算只花了5秒钟,这是ToString的过程需要很长时间。
答案 1 :(得分: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。告诉我们我们需要(2 57885161 )2 (2 25 ) * 2 (2 24 ) * 2 (2 22 )等...我们可以在计算所需的最高值时存储所需的2个幂,然后只需做最后的乘法。那就是25 + 13大整数乘法。然后我们只需要扣除1以获得所需的值。
答案 2 :(得分:-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 Framework计算每个表达式所需的时间。
如果事实证明所需的时间太长,那么您可以尝试自己进行计算。您应该使用此algorithm to perform the exponentiation,然后从C ++移植到C#my own implementation of big integers multiplication或您可能找到的任何其他端口。但是,由于您仍在使用托管代码,因此无保证您将获得更好的性能。