算法一:关于大数运算的阶乘 (基=10) c语言程序代码注释
2014-10-17 16:14
267 查看
大数运算也是刚刚接触 ,因此找了资料和代码熟悉下。从搜索情况来看,阶乘被人提及比较多。因此我也在搜到文章中 选了一个代码,进行了注释。
代码不难,是一位博主写的。但是代码没有注释,我为了方便以后自己观看 和 与大家交流 贴出来分享下 。可能有些地方不是很对,欢迎指正,杜绝恶意评价。
下期预告:十六进制转成十进制,特别之处在于可以输入任意长度的十六制,也属大数运算。
网上有类似的,但希望自己能有一个学习过程的记录。 希望自己能坚持更新下来。贵在坚持
代码不难,是一位博主写的。但是代码没有注释,我为了方便以后自己观看 和 与大家交流 贴出来分享下 。可能有些地方不是很对,欢迎指正,杜绝恶意评价。
下期预告:十六进制转成十进制,特别之处在于可以输入任意长度的十六制,也属大数运算。
网上有类似的,但希望自己能有一个学习过程的记录。 希望自己能坚持更新下来。贵在坚持
#include "stdint.h" #include "string.h" #include "stdio.h" //定义short int 为 s_int 16位 #define s_int short int //定义最大的位数(指结果值) #define MAXDIGIT 50000 //定义权 也就是基数为10 #define RADIX 10 //定义一个函数实现进位 //返回值为bool 表明正确与否 bool carry(s_int result[],int &dgts){ int i; s_int carry_value = 0; //这里将上次计算得到的结果值(未进位) 并告知当前结果值占的位数 //比如上次 3! * 4后=24 但是是存储在result[0]中的 digits=0 //当然下面的肯定不会执行(因为digits=0) 不要急 因为它的 //下面一个就是处理他的问题 for(i=0;i<dgts;i++) { result[i] +=carry_value ;//从最低位开始计算 初始进位值为0 //判断该位是否需要进位 然后计算进位值 //比如12 那么进位为1(添加到result[1]上) 余数为2(存储在result[0]) carry_value =(result[i]< RADIX)?0:(result[i]/RADIX); result[i] -= carry_value * RADIX; //进位后以后得到的该位置值 } //处理最后一位 //若需要进位,则循环进位,直到需要进位为止 //注意 这里i是+1后的 result[i] += carry_value; while(result[i]>=RADIX && i<MAXDIGIT) { carry_value = result[i] / RADIX; result[i] -= carry_value * RADIX; result[++i] = carry_value; ++dgts; } if(i >= MAXDIGIT) return false; return true; } //定义一个阶乘函数 factorial //返回值是一个int类型 其实就是标志 出错就返回-1 //传入n 即 你要求的那个数的阶乘n! result 指代结果值 int factorial(int n ,s_int result[]) { int digits = 0; //位数记录 初始设为0 result[0] = 1 ; //结果初始为1 //0!=1 if(n==0) return 1;//返回1只是表明计算正确 结果值其实在上面的初始化result[0]=1 //开始计算n! 这里我们从2开始 是因为1没有必要 //比如求4! 那么就是1 * 2 * 3 *4 所以这里用n+1 for(int i=2;i<n+1;i++){ //以下都是前一次result[] 乘以i值 for(int j=0;j<=digits;++j) { //关键一步 如果一个数用数组来存储 /* 举例: 5! 先看4! 4! = 3!* 4 = 2! * 3 * 4 2! = 2*1 省略1 就是i从2开始 得到的结果值存在result[]数组中 result每一个元素都能存0-9的数 比如3!= 6那么存到result[0]中 4!=12 那么只存到result[0]就不够了 因为result[0]只能存0-9 但是结果是12 所以我们要把多余的放到result[1]中 相当于进位了1 result[0] 只剩下2了 而result[1]原来是0 现在+1 result[1] = 1; ok 现在来看5! =4!* 5 =24 * 5 12 不能用整体来看 而是分别存储在result[1] reuslt[0]中 1 2 来看 那么*5 是最低位开始乘 也就是 2*5 即下文result[0] * 5 然后是 result[1]* 5 先不进位 只是存储在各自的result[i]位中 注意: result[]要计算多少位 是根据digits 位数来进行的 比如一开始 digits = 0 是因为结果值只占一位 存储在result[0] 后来4!=12 那么就要 存储到result[1] 和result[0] digits=1 */ result[j] *= i; } //上面已经把 计算结果值 写入到各自的位中 下面要判断进位 也就是 每乘以一个数就要判断进位一次 //比如 9!=8!*9 =7!*8*9=...=1!*2 *3*...*9 每次都是上一次结果 * 数n(从2,3,4,5...9为止) if(!carry(result,digits)) break; } } //定义一个打印函数 void print(s_int result[],const int &digits){ int i; if(digits <10) { for(int i = digits;i>=0;i--) { printf("%d",result[i]); } }else{ printf("%d.",result[digits]); for(i=digits-1;i>0;i--) { printf("%d",result[i]); } printf("E %d",digits); } } //主程序入口 int main(void) { s_int result[MAXDIGIT]; int n; int digits; //提示信息 printf("Please input the number that you want to calulate the n!\n"); //用户输入n 求n! scanf("%d",&n); //判断n值 限制条件可以自己设定 if(n < 0) { printf("Error:A positive integer is needed!"); return 0; } //主要算法和函数 函数包括:计算n! 和 打印结果值 if((digits = factorial(n,result))== -1){ printf("over flow"); return 0; }else { print(result,digits); return 0; } }
相关文章推荐
- WV.30-大数阶乘算法10-用Stirling逼近近似计算阶乘的探讨与应用
- 2018年全国多校算法寒假训练营练习比赛题解(第三场)E进击吧!阶乘(大数运算)
- 10000的阶乘的算法(大数的阶乘) [转]
- 两个大数相加比较符合自然运算的算法
- 高精度运算——大数阶乘、排列、组合
- 大数运算的算法
- 大数运算之100的阶乘(C语言实现)
- 10000的阶乘的算法(大数的阶乘)
- 大数阶乘算法
- 一种计算大数阶乘的算法
- 关于平方根运算的算法
- 吴昊品游戏核心算法 Round 10 —— 关于先前发布的围棋算法(模拟)中目数统计函数的全解析(感谢林安泽)
- 关于大数的阶乘与确定阶乘结果的位数
- 大数阶乘的算法
- 大数阶乘 算法
- 求大数阶乘的算法
- 10000的阶乘的算法(大数的阶乘)
- [导入]关于阶乘的两个常见算法及一个相关面试题
- 大数阶乘算法思想,具体实现网上很多,也顺便找了个算法思想
- VBS函数应用--求大数的阶乘的算法