让我惊讶的效率!

  以前一个很平常的问题,就是怎么去计算大数的问题。当然这里的大数不是说几万或者几十万这样的数字,而是那些……反正就是很大很大的数字,大到我都念不出来。要处理大数,很早以前,我是用一个字符串来模拟数值计算的,感觉算法上没有问题,但是效率上就低的有点让人不能接受了。后来才有同学告诉我,其实可以用数组的,用数字数组,这样一来,操作上跟我用字符串没有什么区别,但是计算的效率上就会大出不少。我也没有真正做过太详细的测试,我同学告诉我,他用字符串处理大数的几个例子。他们是用10000的阶乘来做测试的。结果是,用字符串的方法,要十几分钟才能计算的出来,而改用数字数组以后,是要1秒多一点就OK了。

  就再这个时候,他又用了另一种方法进行了测试,亦即用Java提供的BigInteger来计算10000的阶乘,结果效率上有了大幅度提高,但是也在1000MS左右,具体的应该是800MS左右。今天,我又有了惊人的发现。在网上闲逛的时候,突然看到原来.NET FRAMEWORK 4也提供了BigInteger这种类型了,好奇心的驱使下,我也想在这个环境下来试一下用它来做10000的阶乘的效率如何,结果果然让我很兴奋!测试代码比较简单,如下:

1 using System;
2  using System.Collections.Generic;
3  using System.Linq;
4 using System.Text;
5 using System.Numerics;
6 using System.Diagnostics;
7 namespace BigIn
8 {
9 class Program
10 {
11 static void Main(string[] args)
12 {
13 BigInteger big = new BigInteger();
14 big = 1;
15
16 Stopwatch sp = new Stopwatch();
17 sp.Start();
18 for (int i = 1; i <= 10000; i++)
19 {
20 big *= i;
21 }
22 sp.Stop();
23 Console.WriteLine(big);
24 Console.WriteLine(big.ToString().Length);
25 Console.Write(sp.Elapsed);
26
27 Console.ReadKey();
28 }
29 }
30 }
31

运行结果如下:

上面是计算的结果,可以看到,这个数字已经大的不像话了,有35660位那么多,但是看看它的运行时间,0.1657760S !竟然才165MS!太强大了!

不知道微软这个东西是怎么实现的,如果有路过的朋友知道其中的算法,请指教一下,我真的很好奇……

原文地址:https://www.cnblogs.com/malloc/p/1689746.html