大数的阶乘

版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。 http://jeick.blog.51cto.com/713059/144272
10000的阶乘的算法(大数的阶乘)
  2!=1*2<=10*10
  3!=1*2*3<=10*10*10
.......
所以我们可以得出一个结论
          n!<=10n
所以n!的位数可以这样计算:
两边取对数,即log10n!<=log1010n
两边n>=Log101+Log102+Log10 3+....Log10 n
这样n!的位数肯定等于小于Log101+Log102+Log10 3+....Log10 n.
以上是错误的
正确的推断如下:
可以将n!表示成10的次幂,即n!=10^M(10的M次方)则不小于M的最小整数就是 n!的位数,
对该式两边取对数,有=log10^n!即:
M = log10^1+log10^2+log10^3...+log10^n
循环求和,就能算得M值,该M是n!的精确位数。

位数的确定解决之后,就看看如何计算了.
看看如下代码:
 1int index=0;
 2    long carrier=0;
 3    double bitCount = 1;
 4    int begin = 0;
 5 
 6    for(index=2; index<=n; ++index)
 7    {
 8        long multiValue = 0;  
 9        bitCount += log10((long double)index);
10        if(arrValue[begin] == 0)
11            begin++;
12 
13        for(int j=begin; j<int(bitCount); ++j)
14        {
15            multiValue += (index*arrValue[j]);
16            arrValue[j] = char(multiValue % 10);
17            multiValue /= 10;
18        }
19    }
这里就是计算的关键了.注意一下进位问题即可.所有代码如下:
  1
  2/**///
  3//      Date created:    2005/07/12
  4//     Author:        Confach Zhang
  5//     Purpose:         计算n!的值
  6/**///
  7
  8 
  9using namespace std;
 10#include "StdAfx.h"
 11#include <iostream.h>
 12#include <conio.h>
 13#include <stdlib.h>
 14#include <math.h>
 15#include <stdio.h>
 16#include <iomanip.h>
 17 
 18int GetNumber();                                   //输入 n
 19int GetBitLength(int n);                           //求n!的位数
 20char* Initialize(int);                             //初始化存储结果的值
 21void PrintValue(char *a,int size);                 //打印值到屏幕
 22void PrintValue(char *a,int size,char* fileName);  //打印值到文件
 23char* GetValue(int val);                           //计算
 24char* SubGetValue(char* ,int);                     
 25
 26
 27int main()
 28{
 29    int value=GetNumber();
 30    char fileName[16];
 31    int size=GetBitLength(value);
 32    char *pa = Initialize(size);
 33
 34    //pa=GetValue();
 35    pa=GetValue(value);
 36
 37    PrintValue(pa,size);
 38
 39    //sprintf(fileName,"%s","10000!.txt");
 40    sprintf(fileName,"%d!.txt",value);
 41   
 42    PrintValue(pa,size,fileName);
 43    delete []pa;  //note:
 44    return 1;
 45}
 46//函数GetValue
 47// 求得计算结果
 48//返回结果
 49//History:
 50//1)char* GetValue()
 51//2)GetValue(int val)
 52//  参数:val 计算阶乘的值
 53char* GetValue(int val)
 54{
 55    //定义一个数组存储阶乘的值
 56    //首先得到10000!阶乘的位数
 57    int VALUE=val;
 58    int length=GetBitLength(VALUE);
 59    char *arrValue = new char[length];
 60    if(!arrValue) {
 61        cout <<"申请内存失败!" << endl;
 62        exit(1);
 63    }
 64    arrValue[0] = 1;
 65    for(int i=1; i<length; i++)
 66        arrValue[i] = 0;
 67    arrValue=SubGetValue(arrValue,VALUE);
 68    return arrValue;
 69}
 70
 71char* SubGetValue(char* arrValue,int n)
 72{
 73    int index=0;
 74    long carrier=0;
 75    double bitCount = 1;
 76    int begin = 0;
 77 
 78    for(index=2; index<=n; ++index)
 79    {
 80        long multiValue = 0;  
 81        bitCount += log10((long double)index);
 82        if(arrValue[begin] == 0)
 83            begin++;
 84 
 85        for(int j=begin; j<int(bitCount); ++j)
 86        {
 87            multiValue += (index*arrValue[j]);
 88            arrValue[j] = char(multiValue % 10);
 89            multiValue /= 10;
 90        }
 91    }
 92  return arrValue;
 93}
 94
 95//得到计算阶乘的值,此函数为新增
 96int GetNumber()
 97{
 98    int n;
 99    cout << "请输入要计算阶乘的n值: ";
100    cin >> n;
101    while(n < 0) {
102        cout << "输入错误,请重新输入: ";
103        cin >> n;
104    }
105    if(n == 0)
106        exit(1);
107    return n;
108}
109
110//函数GetBitLength
111// 求得计算结果的位数,本函数为新增加
112//参数
113//     n 需要计算的阶乘的数
114//返回结果的位数
115int GetBitLength(int n)
116{
117    double sum = 1.0;
118    for(int i=1; i<=n; i++)
119        sum += log10((long double)i);
120    return int(sum);
121}
122//-----------
123//函数:Initialize
124//   初始化存储结果的数组
125//参数:
126//     size      数组的长度 
127//返回值
128//    初始化后的数组
129//-------------
130char * Initialize(int size)
131{
132    char *arrValue = new char[size];
133    if(!arrValue) {
134        cout << size<<"太大,申请内存失败!" << endl;
135        exit(1);
136    }
137    arrValue[0] = 1;
138    for(int i=1; i<size; i++)
139        arrValue[i] = 0;
140    return arrValue;
141}
142 
143//-----------
144//函数:PrintValue
145//   将结果输入到屏幕上
146//参数:
147//     buff      存储结果的数组
148//   buffLen   数组的长度
149//   fileName  文件名        
150//-------------
151void PrintValue(char *buff, int buffLen)
152{
153    int bit = 0;
154    int nCol=0;
155    for(int i=buffLen-1; i>=0; i--) {
156        if(bit % 10 == 0)
157        {
158            cout << " " ;
159            nCol++;
160            if(nCol==10)cout<<endl;
161        }
162          cout << int (buff[i]);  
163        bit++;
164    }
165    cout << endl;
166   
167}
168//-----------
169//函数:PrintValue
170//   将结果输入到一个文件中
171//参数:
172//     buff      存储结果的数组
173//   buffLen   数组的长度
174//   fileName  文件名        
175//-------------
176
177void PrintValue(char *buff,int buffLen,char *fileName)
178{
179     int bit = 0;
180    int nCol=0;
181
182    FILE *fp=NULL;
183    //-----------------------------
184
185    if (fileName==NULL)        return ;
186    fp=fopen(fileName,"wt");
187    if (fp==NULL)
188    {
189        printf("不能创建文件%s",fileName);
190        return ;
191    }
192
193    for(int i=buffLen-1; i>=0; i--)
194    {
195        fprintf(fp,"%d",int(buff[i]));
196       
197         if(bit % 9 == 0)
198        {
199            fprintf(fp,"%s"," ");
200            nCol++;
201            if(nCol==8)
202            {
203                fprintf(fp,"%s","/n");
204                nCol=0;
205            }
206        }
207        bit++;
208       
209    }
210    fprintf(fp,"/n");
211    fclose(fp);
212}
213

本文出自 “Jeick(编程菜鸟)” 博客,请务必保留此出处http://jeick.blog.51cto.com/713059/144272

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值