网站开发 指导,windows7怎么做网站服务器,免费下载教学设计的网站,风雨同舟网站建设大数的四则运算#xff08;加法、减法、乘法、除法#xff09; 前言#xff1a; 在计算机中数字表示的范围是有限制的#xff0c;比如我们熟知的 int、float、double 等数据类型所能表示的范围都是有限的#xff0c;如果我们要对位数达到几十位、几百位、上千位的大整数进… 大数的四则运算加法、减法、乘法、除法 前言 在计算机中数字表示的范围是有限制的比如我们熟知的 int、float、double 等数据类型所能表示的范围都是有限的如果我们要对位数达到几十位、几百位、上千位的大整数进行计算这些数据类型显然不能满足我们的要求因此我们需要通过算法来实现这些功能。 1、大数加法 两个大数我们可以用数组来保存然后在数组中逐位进行相加再判断该位相加后是否需要进位为了方便计算我们将数字的低位放在数组的前面高位放在后面。 下面是两个正的大整数相加算法的C语言参考代码 1 #includestdio.h2 #includestring.h3 4 #define MAX 1000 // 大数的最大位数 5 6 7 /*8 大数加法 9 参数
10 num1为第一个大数用字符数组保存
11 num2为第二个大数
12 sum数组保存相加的结果 即num1num2sum
13 返回值返回数组sum的有效长度即计算结果的位数
14 */
15 int Addition(char num1[], char num2[], int sum[])
16 {
17 int i, j, len;
18 int n2[MAX] {0};
19 int len1 strlen (num1); // 计算数组num1的长度即大数的位数
20 int len2 strlen (num2); // 计算数组num2的长度即大数的位数
21
22 len len1len2 ? len1 : len2; // 获取较大的位数
23 //将num1字符数组的数字字符转换为整型数字且逆向保存在整型数组sum中即低位在前高位在后
24 for (i len1-1, j 0; i 0; i--, j)
25 sum[j] num1[i] - 0;
26 // 转换第二个数
27 for (i len2-1, j 0; i 0; i--, j)
28 n2[j] num2[i] - 0;
29 // 将两个大数相加
30 for (i 0; i len; i)
31 {
32 sum[i] n2[i]; // 两个数从低位开始相加
33 if (sum[i] 9) // 判断是否有进位
34 { // 进位
35 sum[i] - 10;
36 sum[i1];
37 }
38 }
39 if(sum[len] ! 0) // 判断最高位是否有进位
40 len;
41 return len; // 返回和的位数
42 }
43
44 int main()
45 {
46 int i, len;
47 int sum[MAX] {0}; // 存放计算的结果低位在前高位在后即sum[0]是低位
48 char num1[] 1234567891234567891234; // 第一个大数
49 char num2[] 2345678912345678913345; // 第二个大数
50 len Addition(num1, num2, sum); // 两数相加
51 printf(%s\n \n%s\n \n, num1, num2);
52 // 反向输出求和结果
53 for (i len-1; i 0; i--)
54 printf(%d, sum[i]);
55 printf(\n);
56 return 0;
57 } 2、大数减法 相减算法也是从低位开始减的。先要判断被减数和减数哪一个位数长若被减数位数长是正常的减法若减数位数长则用被减数减去减数最后还要加上负号当两数位数长度相等时最好比较哪一个数字大否则负号处理会很繁琐处理每一项时要如果前一位相减有借位就先减去上一位的借位无则不减再去判断是否能够减开被减数如果减不开就要借位后再去减同时置借位为1否则置借位为0。 下面是C语言参考代码 1 #includestdio.h2 #includestring.h3 4 #define MAX 1000 // 大数的最大位数 5 6 7 /*8 大数减法 9 参数 10 num1为被减数用字符数组保存11 num2为减数 12 sum数组保存相减的结果 即num1-num2sum13 返回值返回数组sum的有效长度即计算结果的位数 14 */15 int Subtraction(char num1[], char num2[], int sum[])16 {17 int i, j, len, blag;18 char *temp;19 int n2[MAX] {0};20 int len1 strlen(num1); // 计算数组num1的长度即大数的位数 21 int len2 strlen(num2); // 计算数组num2的长度即大数的位数22 23 // 在进行减法之前要进行一些预处理 24 blag 0; // 为0表示结果是正整数为1表示结果是负整数 25 if(len1 len2) // 如果被减数位数小于减数26 {27 blag 1; // 标记结果为负数28 // 交换两个数便于计算 29 temp num1;30 num1 num2;31 num2 temp;32 len len1;33 len1 len2;34 len2 len;35 }36 else if(len1 len2) // 如果被减数的位数等于减数的位数37 { 38 // 判断哪个数大 39 for(i 0; i len1; i)40 {41 if(num1[i] num2[i])42 continue;43 if(num1[i] num2[i])44 {45 blag 0; // 标记结果为正数 46 break;47 } 48 else49 {50 blag 1; // 标记结果为负数 51 // 交换两个数便于计算 52 temp num1;53 num1 num2;54 num2 temp;55 break;56 } 57 } 58 }59 len len1len2 ? len1 : len2; // 获取较大的位数60 //将num1字符数组的数字转换为整型数且逆向保存在整型数组sum中即低位在前高位在后61 for (i len1-1, j 0; i 0; i--, j) 62 sum[j] num1[i] - 0;63 // 转换第二个数 64 for (i len2-1, j 0; i 0; i--, j)65 n2[j] num2[i] - 0;66 // 将两个大数相减 67 for (i 0; i len; i)68 {69 sum[i] sum[i] - n2[i]; // 两个数从低位开始相减 70 if (sum[i] 0) // 判断是否有借位 71 { // 借位 72 sum[i] 10;73 sum[i1]--;74 }75 }76 // 计算结果长度 77 for (i len1-1; i0 sum[i] 0; i--)78 ;79 len i1;80 if(blag1)81 {82 sum[len] -1; // 在高位添加一个-1表示负数 83 len;84 }85 return len; // 返回结果的位数 86 }87 88 int main()89 {90 int i, len;91 int sum[MAX] {0}; // 存放计算的结果低位在前高位在后即sum[0]是低位 92 char num1[] 987654321987654321; // 第一个大数 93 char num2[] 123456789123456789; // 第二个大数 94 len Subtraction(num1, num2, sum); // 两数相减 95 // 输出结果96 printf(%s\n -\n%s\n \n, num1, num2);97 if(sum[ilen-1] 0) // 根据高位是否是-1判断是否是负数98 {99 printf(-); // 输出负号
100 i--;
101 }
102 for (; i 0; i--)
103 printf(%d, sum[i]);
104 printf(\n);
105 return 0;
106 } 3、大数乘法 首先说一下乘法计算的算法从低位向高位乘在竖式计算中我们是将乘数第一位与被乘数的每一位相乘记录结果之后用第二位相乘记录结果并且左移一位以此类推直到计算完最后一位再将各项结果相加得出最后结果。 计算的过程基本上和小学生列竖式做乘法相同。为了编程方便并不急于处理进位而是将进位问题留待最后统一处理。 总结一个规律: 即一个数的第i 位和另一个数的第j 位相乘所得的数一定是要累加到结果的第ij 位上。这里i, j 都是从右往左从0 开始数。 ans[ij] a[i]*b[j]; 另外注意进位时要处理当前的值加上进位的值再看本位数字是否又有进位前导清零。 下面是C语言的两个正大数相乘的参考代码 1 #includestdio.h2 #includestring.h3 4 #define MAX 1000 // 大数的最大位数 5 6 7 /*8 大数乘法 9 参数
10 num1为第一个因数用字符数组保存
11 num2为第二个因数
12 sum数组保存相乘的结果 即num1*num2sum
13 返回值返回数组sum的有效长度即计算结果的位数
14 */
15 int Multiplication(char num1[],char num2[], int sum[])
16 {
17 int i, j, len, len1, len2;
18 int a[MAX10] {0};
19 int b[MAX10] {0};
20 int c[MAX*210] {0};
21
22 len1 strlen(num1);
23 for(j 0, i len1-1; i 0; i--) //把数字字符转换为整型数
24 a[j] num1[i]-0;
25 len2 strlen(num2);
26 for(j 0, i len2-1; i 0; i--)
27 b[j] num2[i]-0;
28
29 for(i 0; i len2; i)//用第二个数乘以第一个数,每次一位
30 {
31 for(j 0; j len1; j)
32 {
33 c[ij] b[i] * a[j]; //先乘起来,后面统一进位
34 }
35 }
36
37 for(i0; iMAX*2; i) //循环统一处理进位问题
38 {
39 if(c[i]10)
40 {
41 c[i1]c[i]/10;
42 c[i]%10;
43 }
44 }
45
46 for(i MAX*2; c[i]0 i0; i--); //跳过高位的0
47 len i1; // 记录结果的长度
48 for(; i0; i--)
49 sum[i]c[i];
50 return len;
51 }
52
53 int main()
54 {
55 int i, len;
56 int sum[MAX*210] {0}; // 存放计算的结果低位在前高位在后即sum[0]是低位
57 char num1[] 123456789123456789; // 第一个大数
58 char num2[] 123456789123456789; // 第二个大数
59 len Multiplication(num1, num2, sum);
60 // 输出结果
61 printf(%s\n *\n%s\n \n, num1, num2);
62 for(i len-1; i0; i--)
63 printf(%d, sum[i]);
64 printf(\n);
65 return 0;
66 } 4、大数除法 大数除法是四则运算里面最难的一种。不同于一般的模拟除法操作不是模仿手工除法而是利用减法操作来实现的。其基本思想是反复做除法看从被除数里面最多能减去多少个除数商就是多少。逐个减显然太慢要判断一次最多能减少多少个整数(除数)的10的n次方。 以7546除以23为例 先用7546减去23的100倍即减去2300可以减3次余下646此时商就是300 (300100*3) 然后646减去23的10倍即减去230可以减2次余下186此时商就是320 (32030010*2) 然后186减去23可以减8次余下2此时商就是328 (3283201*8) 因为2除以23的结果小于1而我们又不用计算小数点位所以不必再继续算下去了。 下面是C语言的两个正大数相除的参考代码计算结果中没有小数 1 #includestdio.h2 #includestring.h 3 #define MAX 1000 // 大数的最大位数 4 5 // 注 6 // 本代码在以下博客代码中进行修改 7 // http://www.cnblogs.com/javawebsoa/archive/2013/08/01/3231078.html8 // 9 10 11 /*12 函数SubStract功能13 用长度为len1的大整数p1减去长度为len2的大整数p214 结果存在p1中返回值代表结果的长度15 不够减返回-1 正好够返回016 */ 17 int SubStract(int *p1, int len1, int *p2, int len2)18 {19 int i;20 if(len1 len2)21 return -1;22 if(len1 len2 )23 { // 判断p1 p224 for(i len1-1; i 0; i--)25 {26 if(p1[i] p2[i]) // 若大则满足条件可做减法27 break;28 else if(p1[i] p2[i]) // 否则返回-129 return -1;30 }31 }32 for(i 0; i len1-1; i) // 从低位开始做减法33 {34 p1[i] - p2[i]; // 相减 35 if(p1[i] 0) // 若是否需要借位36 { // 借位 37 p1[i] 10;38 p1[i1]--;39 }40 }41 for(i len1-1; i 0; i--) // 查找结果的最高位42 {43 if( p1[i] ) //最高位第一个不为044 return (i1); //得到位数并返回45 } 46 return 0; //两数相等的时候返回047 }48 49 50 /*51 大数除法---结果不包括小数点 52 num1 被除数53 num2 除数 54 sum 商存放计算的结果即num1/num2sum55 返回数组sum的有效长度即商的位数 56 */ 57 int Division(char num1[], char num2[], char sum[])58 {59 int k, i, j;60 int len1, len2, len0; //大数位数61 int dValue; //两大数相差位数62 int nTemp; //Subtract函数返回值63 int num_a[MAX] {0}; //被除数64 int num_b[MAX] {0}; //除数65 int num_c[MAX] {0}; //商 66 67 len1 strlen(num1); //获得大数的位数68 len2 strlen(num2);69 70 //将数字字符转换成整型数且翻转保存在整型数组中 71 for( j 0, i len1-1; i 0; j, i-- )72 num_a[j] num1[i] - 0;73 for( j 0, i len2-1; i 0; j, i-- )74 num_b[j] num2[i] - 0;75 76 if( len1 len2 ) //如果被除数小于除数直接返回-1表示结果为077 {78 return -1;79 }80 dValue len1 - len2; //相差位数81 for (i len1-1; i 0; i--) //将除数扩大使得除数和被除数位数相等82 {83 if (i dValue)84 num_b[i] num_b[i-dValue];85 else //低位置086 num_b[i] 0;87 }88 len2 len1;89 for(j 0; j dValue; j ) //重复调用同时记录减成功的次数即为商90 {91 while((nTemp SubStract(num_a, len1, num_bj, len2-j)) 0)92 {93 len1 nTemp; //结果长度94 num_c[dValue-j]; //每成功减一次将商的相应位加195 }96 }97 // 计算商的位数并将商放在sum字符数组中 98 for(i MAX-1; num_c[i] 0 i 0; i-- ); //跳过高位0获取商的位数 99 if(i 0)
100 len i 1; // 保存位数
101 for(j 0; i 0; i--, j) // 将结果复制到sum数组中
102 sum[j] num_c[i] 0;
103 sum[j] \0; // sum字符数组结尾置0
104 return len; // 返回商的位数
105 }
106
107
108 int main()
109 {
110 int i;
111 int len; // 商的位数
112 char num1[MAX] 1234567899876543210; // 第一个大数
113 char num2[MAX] 20160415123025; // 第二个大数
114 char sum[MAX] {0}; // 计算结果
115
116 //scanf(%s, num1); //以字符串形式读入大数
117 //scanf(%s, num2);
118
119 len Division(num1, num2, sum);
120
121 //输出结果
122 printf(%s\n ÷\n%s\n \n, num1, num2);
123 if( len0 )
124 {
125 for(i 0; i len; i )
126 printf(%c, sum[i]);
127 }
128 else
129 {
130 printf(0);
131 }
132 printf(\n);
133
134 return 0;
135 } 5、使用Java提供的类 在Java中提供了BigInteger类和BigDecimal类分别用来处理大整数和大浮点数我们只要调用里面提供的方法就能很方便的进行大数的四则运算具体实现可参考