有关大数字运算的讨论

来源:互联网 发布:废旧网络机顶盒改装 编辑:程序博客网 时间:2024/06/02 10:46

 

    昨天闲来无事我写了两个计算大数字阶乘和乘方的程序。写这个东西主要原因是因为我的第一次面试。今年春天我去北京一家很不错的公司面试,其中有一项是笔试,命题人出了一道这样的题:试计算2^256,写出编程思想,不要求最后结果。作为一名还未走出校门的学生,其实应变这样的一道题应该说也不算太难,思路很简单,就是用一个数组存储结果,其中每个数项治村结果的几位,然后按照像《计算机组成原理》中介绍的乘法器那样进行逻辑实现。我当时就是这么很简单的写了一个实现思路,当时面试的9个人中,做对这道题的人只有我一个,因此我就凭这道题为自己争得了一个很高的印象分,虽然后来由于某些原因我没有去那家公司,但是这也算是我的一次面试成功经历,所以还是记忆犹新。下面是我在UNIX下编写的计算阶乘的程序,其实现思路和乘方运算差不多。具体流程注释中应该很清楚了。

#include <stdio.h>

/****************

此函数fact()实现计算大数字阶乘

参数 n int

返回结果整形数为0则表示出错,否则打印结果

*****************/

int fact(int n)

{

        int a[900];/*记录结果*/

 

        int flag=1;/*结果位数标志*/

        int data=n;/*计算过程中的被乘数*/

        int i = 0;/*循环标志*/

/*只对0———1041之间的数进行计算*/

        if((n < 0)||(n > 1042))

        {

                printf("数字溢出!/n");

                return 0;

        }

        /*0的阶乘单独处理*/

        if(n == 0)

        {

                printf("0 !=1/n ");

                return 0;

        }

       /*如果输入的值大于2位,初始化头两个数组值*/

        if(n >= 1000)

{

        flag = 2;

        }

        a[0] = 1;

        /*主运算*/

        while((data > 0)&&(flag < 900))

        {

             /*将上次的结果和下一个被乘数进行一轮运算*/

                for(i=0; i<flag; i++)

                {

                        a[i] = a[i] * data;

                }

             /*调整结果*/

                for(i=0; i<flag-1; i++)

                {

                        a[i+1] += a[i]/1000;

                        a[i] = a[i] % 1000;

                }

            /*调整结果*/

                if(a[flag-1] > 1000)

                {

                        flag++;

                        a[i+2] = a[i+1] / 1000;

                        a[i+1] = a[i+1] % 1000;

                }

           /*被乘数自减*/

                data--;

        }

         /*结果的打印*/

printf("%d != ",n);

        printf("%d",a[flag-1]);

         /*针对三位数字的头两位是否为0进行处理*/

        for(i=flag-2; i>=0; i--)

        {

                if(a[i]<100)

                printf("0");

                if(a[i]<10)

                printf("0");

                printf("%d",a[i]);

        }

        printf("/n");

        return 1;

}

main()

{

fact(1000);

}

执行结果:

1000 != 40238726007709377354370243392300398571937486421071463254379991042

99385123986290205920442084869694048004799886101971960586316668729

94808558901323829669944590997424504087073759918823627727188732519

77950595099527612087497546249704360

……(限于篇幅,这里就不再罗列太多的数字)00000000000000000000000000000000000000000000000000000000000000000

00000000000000000000000000000000000000000000000000000000000000000

00000000000000000000000000000000000000000000000

这样一段计算大数字阶乘的代码就完成了,很简单吧!但是说到简单,我还见到不知出自何处的这样一段代码,风格好坏暂且不管,即使有人称之为是一小堆垃圾代码,但是它能计算pi到小数点后面1000位之多,你说厉害么?

#include <stdlib.h>

#include <stdio.h>

main()

{

        long a=10000,b,c=2800,d,e,f[2801],g;

        for(;b-c;)

         f[b++]=a/5;

        for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a)

         for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);

   }

打印结果:

31415926535897932384626433832795028841971693993751058209749445923

07816406286208998628034825342117067982148086513282306647093844609

55058223172535940812848111745028410270193852110555964462294895493

03819644288109756659334461284756482337867831652712019091456485669

23460348610454326648213393607260249141273724587006606315588174881

52092096282925409171536436789259036001133053054882046652138414695

19415116094330572703657595919530921861173819326117931051185480744

62379962749567351885752724891227938183011949129833673362440656643

08602139494639522473719070217986094370277053921717629317675238467

48184676694051320005681271452635608277857713427577896091736371787

21468440901224953430146549585371050792279689258923542019956112129

02196086403441815981362977477130996051870721134999999837297804995

10597317328160963185

当然如果数学基础比较好的同学可以利用一些有关级数的公式,很容易写出计算pi小数点后上万位的代码,可能也不会超过几十行,但是要想精简到此种程度也着实不易。

上面介绍的只不过是大数字运算的一点皮毛,真正涉及到理论的东西远不止这么肤浅,除非你是专门研究这个的或者有很新的创意,否则根本用不着费那么大的力气去自己编写一些进行大数字运算的函数,如果只是为了应用,你可以选择象Maple那样的数学软件,它的大数字运算足以满足你的需求,它可以一下打印出10000!,数字可以滚好几屏!

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝吃奶粉太勤怎么办 香蕉和地瓜一起吃了怎么办 贝亲奶瓶泡沫多怎么办 四个多月的宝宝拉肚子怎么办 宝宝四个月了拉肚子怎么办 四个月宝宝火大怎么办 刚出生的宝宝便秘怎么办 小宝宝破腹产吸了几口羊水怎么办 换奶粉不拉屎了怎么办 婴儿吃奶粉不拉屎怎么办 1岁半突然不喝奶怎么办 6个月宝宝不吃奶粉怎么办 7个月宝宝不吃奶粉怎么办 5个月宝宝不吃奶粉怎么办 一岁两个月宝宝不长肉怎么办 7个月宝宝肚子疼怎么办 奶喝一半凉了怎么办 5个月孩子厌奶怎么办 怀孕后特别不爱吃水果怎么办 宝宝吃了无比滴怎么办 婴儿上火怎么办吃什么可以去火 肚子胀怎么办最快的方法 40天婴儿拉水怎么办 8个月宝宝坐不稳怎么办 宝宝段奶不吃奶粉怎么办 3个月宝宝头睡偏了怎么办 2个月婴儿抱着睡怎么办 两个半月的宝宝睡眠少怎么办 七个月宝宝不愿意坐怎么办 一个多月的宝宝老是哭闹怎么办 宝宝头老往后仰怎么办 8个月宝宝不会爬怎么办 孩子个头长得慢怎么办 宝宝个头长得慢怎么办 婴儿个头长得慢怎么办 11个月宝宝认生怎么办 3个月宝宝认人怎么办 3个月的宝宝认生怎么办 两个月的宝宝睡觉一惊一惊怎么办 六个月宝宝不喜欢喝水怎么办 三岁宝宝尿多怎么办