大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE稳定放心使用
前言:
本篇博客将分为4到5篇来和大家一块讨论大数的加减乘除,然后再将运算做成一个大数运算库。其中除法较为棘手,但如果作完前三个运算后就没有什么难度了。虽然大多主流的编程语言如java,c++,都有大数运算库,可是c语言标准库并没有提供的大数运算,网上的c语言大数运算大多散而不周或过于复杂,所以本人决定写博客做一些简单的介绍,由于本人水平有限,如有错误或者bug请大家批评指正我会第一时间更正。
开发环境:
本人没有windows电脑,所有的编写测试都是在centos 3.10.-514.6.1.el7.x86_64 和 gcc 4.8.5 下做的,windows平台下没有任何测试,所以如果windows下出现错误我也无能为力。
总体思路:
加法和减法类似,乘法和除法类似,我们会先从大数加减法开始然后是乘除法。使用数组作为数据结构保存用户的输入和结果,主要就是将大数的整体运算转换为每一个数组元素的运算,难点也就在转换上。
大数减法:
假设 :
用户输入的数据保存在数组adda与数组addb中,adda={1,2,3,4,5,6,7,8,9};addb={1,2,3,4}。如果模仿手工计算,从低位到高位以次先加,满十则进一,那么将会有两个问题要解决。
问题:
1.用数组保存结果那么结果的长度是多少位?
2.如何写一个满十进一的算法。
其实这两个问题也很简单:
1.二个数相加结果最大只会比较大的数多一位,所以:用lensum代表结果的长度lena代表adda的长度,lenb代表addb的长度。
lensum=lena>lenb?lena:lenb;
lensum++;
就可以确定结果数组的长度。
2.如果每加一位就判断是否进一的话问题就会复杂一点,所以我们可以先保存每一位相加的结果然后在对结果进行处理如图。
一次性对result进行处理就很好实现:
for(i=lensum-1;i>0;i--){
if(result[i]>9){
result[i]=result[i]%10;
result[i-1] += 1;
}
}
注意实际的程序,会把9+4的结果存在result[0]中,8+3的结果存在result[1]中,上面的图是为了简化方便理解,其实也可以像图中那样存把循环控制的i由递增改成递减就可以了。
实现:
我会将加法写成方法,然后在main函数中调用,这样方便以后做成一个自己的库,代码很完整注释也很多。很好懂的。
1 //#include"big.h"
2 //将整个加法写成一个方法,然后在main函数中调用。
3 #include<stdlib.h>
4 #include<stdio.h>
5 #include<string.h>
6 char * bigadd(char *adda,int lena,char *addb,int lenb){ //加法运算的方法。
7 int num='0',i,k,j,tmp;
8 for(i=0;i<lena;i++){ //将字符编码的数字转换为对应的数,
9 adda[i]=adda[i]-num; //例如6实际在字符串中存储的是54,
10 } //减去0对应的48得到真实的6存储在字符数组中。
11 for(i=0;i<lenb;i++){
12 addb[i]=addb[i]-num;
13 }
14 int lensum; //求出结果数组的长度。
15 lensum = lena>lenb?lena:lenb;
16 lensum++;
17 char *result,final[BUFSIZ]; //result用于返回结果集,final数组用于整理结果集。
18 result=(char*)calloc(lensum,1);
19 for(i=0,j=0;i<lena&&j<lenb;i++,j++){ //循环的给每一位作加法
20 result[i]=adda[lena-i-1]+addb[lenb-i-1];
21 }
22 if(lena>lenb){ //使用判断将较大数的高位也写入结果数组
23 for(i=lenb;i<lena;i++){
24 result[i]=adda[lena-i-1];
25 }
26 }
27 if(lenb>lena){
28 for(i=lena;i<lenb;i++){
29 result[i]=addb[lenb-i-1];
30 }
31 }
32 for(k=0;k<lensum-1;k++){ //整理结果数组的每一位,满10进一。
33 if(result[k]>9){
34 tmp=result[k]/10;
35 result[k]=result[k]%10;
36 result[k+1] += tmp;
37 }
38 }
39 j=0;
40 if(result[lensum-1]!=0){ //去掉前前导0将结果处理后写到final数组中。
41 final[j]=result[lensum-1]+'0';
j++;
43 }
44 for(i=lensum-2;i>=0;i--){
45 final[j++]=result[i]+'0';
46 }
47 result=final; //再把result指针指向final数组中,并返回result指针。
48 return result;
49 }
50 int main(){ //利用main测试方法,用puts打印结果。
51 int lena,lenb;
52 char *result,sa[BUFSIZ],sb[BUFSIZ];
53 scanf("%s",sa);
54 scanf("%s",sb);
55 lena=strlen(sa);
56 lenb=strlen(sb);
57 result=bigadd(sa,lena,sb,lenb);
58 puts(result);
59
60 }
下篇介绍大数减法。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/184924.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...