算法一:关于大数运算的阶乘 (基=10) c语言程序代码注释
发布时间:2020-12-14 02:59:14 所属栏目:大数据 来源:网络整理
导读:大数运算也是刚刚接触,因此找了资料和代码熟悉下。从搜索情况来看,阶乘被人提及比较多。因此我也在搜到文章中 选了一个代码,进行了注释。 代码不难,是一位博主写的。但是代码没有注释,我为了方便以后自己观看 和 与大家交流 贴出来分享下 。可能有些地方
代码不难,是一位博主写的。但是代码没有注释,我为了方便以后自己观看 和 与大家交流 贴出来分享下 。可能有些地方不是很对,欢迎指正,杜绝恶意评价。 下期预告:十六进制转成十进制,特别之处在于可以输入任意长度的十六制,也属大数运算。 网上有类似的,但希望自己能有一个学习过程的记录。 希望自己能坚持更新下来。贵在坚持 #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; } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |