C语言-大数四则运算
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
a[j++]=str1[i]-'0'; len2=strlen(str2); for(j=0,i=len2-1; i>=0; i--)//倒转第二个整数
b[j++]=str2[i]-'பைடு நூலகம்'; for(i=0; i<len2; i++)//用第二个数乘以第一个数,每次一位
for(j=0; j<len1; j++) c[i+j]+= b[i]*a[j]; //先乘起来,后面统一进位
超大数的四则运算
各类型的范围
❖int (16位) -32768~32767 (注:现在大多数的编译器的int型是32位的 也就
是说跟long型的大小一样) ❖long long或__int64(64位)
-9223372036854775808~ 9223372036854775807 ❖float(32位) 精确到小数点后6~7位 ❖double (64位) 精确到小数点后15~16位 (注:平时做题时 都把浮点型数据定义为double 型 避免精度不够出错)
num1[j++] = s1[i] - '0'; for (i = len2-1,j = 0; i >= 0; i --)
num2[j++] = s2[i] - '0'; for (i = 0; i < M; i ++) {
num1[i] += num2[i]; if (num1[i] > 9) {
for(i=0; i<MAX*2; i++)//循环统一处理进位问题 if(c[i]>=10) { c[i+1]+=c[i]/10; c[i]%=10; }
for(i=MAX*2; (c[i]==0)&&(i>=0); i--);//跳过高位的0 if(i>=0)
for(; i>=0; i--) printf("%d", c[i]);
num1[i] -= 10; num1[i+1] ++; } }
for (i = M-1; (i >= 0)&&(num1[i] == 0); i --) ;//找到第一个不是 0的数的位置
if (i >= 0) //从高位到低位输出每个数 for (; i >= 0; i --) printf ("%d",num1[i]);
else printf ("0\n");
}
减法运算的实现
❖算法也是从低位开始减。先要判断减数和被减 数那一个位数长,减数位数长是正常减;被减 数位数长,则被减数减减数,最后还要加上负 号;两数位数长度相等时,最好比那一个数字 大,否则负号处理会很繁琐;处理每一项时要 ,如果前一位相减有借位,就先减去上一位的 借位,无则不减,再去判断是否能够减开被减 数,如果减不开,就要借位后再去减,同时置 借位为1,否则置借位为0。
主要内容
1
数字存储的实现
2
加法运算的实现
3
减法运算的实现
4
乘法运算的实现
5
除法运算的实现
6
幂运算的实现
数字存储的实现
❖大数计算的因数和结果精度一般是少则数 十位,多则几万位。在C/C++语言中定义 的类型中精度最多只有二十多位。一般我 们称这种基本数据类型无法表示的整数为 大整数。如何表示和存放大整数呢?基本 的思想就是:用数组存放和表示大整数。 一个数组元素,存放大整数中的一位。
❖ans[i+j] = a[i]*b[j];
处理中注意问题:
另外进位时要处理,当前的值加 1 上进位的值再看本位数字是否又
有进位;前导清零。
大数乘法
void Multi(char str1[],char str2[]) {
int len1,len2,i,j; int a[MAX+10],b[MAX+10],c[MAX*2+10]; memset (a,0,sizeof(a)); memset (b,0,sizeof(b)); memset (c,0,sizeof(c)); len1=strlen(str1); for(j=0,i=len1-1; i>=0; i--)//把数字倒过来
比如:1664434318
下标 0 1 2 3 4 5 6 7 8 9 1664434318
加法运算的实现
+加数 9 9 8 7 6 5 4 3 2 0 被加数 1 6 6 4 4 3 4 3 0 0 0 1、进位为1 初始化进位为0,各对应 6 2、进位为1 位相加后再加上进位数 5 3、进位为1 2 4、进位为1
减法运算的实现
- 减数 7 6 8 7 6 5 4 3 2 0 被减数 8 9 7 5 4 3 4 3 2 0
9 1、借位为1 初始化借位为0,各对应 6 2、借位为1 位相减后再减上借位数 0 3、借位为0 2 4、借位为0
由低位向高位相加计算,直至所有运算结束
处理中注意问题:
如果被减数大于减数时 1 ,交换两个数再相减,
else printf("0");
pritnf("\n"); }
除法运算的实现
❖首先说一下我们所要的结果,当除数除 不开被子除数时,不用除到小数,当除 数小于被除数时,除数作为余数既可, 不用再向下除了。
基本思路
❖ 基本的思想是反复做减法,看看从被除数里最多 能减去多少个除数,商就是多少。一个一个减显 然太慢,如何减得更快一些呢?以7546 除以 23 为例来看一下:开始商为0。先减去23 的 100 倍,就是2300,发现够减3 次,余下646 。于是商的值就增加300。然后用646减去230 ,发现够减2 次,余下186,于是商的值增加 20。最后用186 减去23,够减8 次,因此最终 商就是328。
最后加个“-”号即可
结果可能会出现前面是 2 一堆0的情况,要处理好
,如当减数为112,而被 减数为111时,会出现 001
乘法运算的实现
❖首先说一下乘法计算的算法,从低位向高 位乘,在竖式计算中,我们是将乘数第一 位与被乘数的每一位相乘,记录结果,之 后,用第二位相乘,记录结果并且左移一 位,以此类推,直到计算完最后一位,再 将各项结果相加。得出最后结果。
请计算: 1、 2 的 1000次幂 2、 2 的 10000次幂 3、 1234567890123456789123456789034 53434534534535345434543
乘上 9387429387492873492873402803482 0938479288374892733453453534
2. 接下来算4×5。此处4×5 的结果代表20 个10, 因此要 aResult[1]+=20,变为:
1. 再下来算4×3。此处4×3 的结果代表12 个 100,因此要 aResult[2]+= 12,变为:
2. 最后算 4×8。此处4×8 的结果代表 32 个 1000,因此要 aResult[3]+= 32,变为:
1. 乘法过程完毕。接下来从 aResult[0]开始向高 位逐位处理进位问题。aResult[0]留下5,把4 加到aResult[1]上,aResult[1]变为51 后,应 留下1,把5 加到aResult[2]上……最终使得 aResult 里的每个元素都是1 位数,结果就算出 来了:
❖总结一个规律:即一个数的第i 位和另一个数的第j 位相乘所得的数,一定是要累加到结果的第i+j 位上。这里i, j 都是从右往左,从0 开始数。
由低位向高位相加计算,直至所有运算结束
理中注意问题:
1. 判断最后数组的长度. 2. 去掉前导零
大数加法
void Add(char s1[],char s2[])//参数为两个字符串数组 {
int num1[M],num2[M]; int i,j; len1 = strlen (s1); len2 = strlen (s2); for (i = len1-1,j = 0; i >= 0; i --)//num1[0]保存的是低位
大数除法
幂运算的实现
❖幂的实现是最为简单的了,国为有了前面 的算法做铺垫,就是调用乘法函数,来循 环去自乘,幂指数相应减1,直到幂指数变 为0时结束。
❖ 计算的过程基本上和小学生列竖式做乘法相同。 为编程方便,并不急于处理进位,而将进位问题 留待最后统一处理。
❖ans[i+j] = a[i]*b[j];
现以 835×49 为例来说明程序的计算过。
1. 先算835×9。5×9 得到45 个1,3×9 得到27 个10,8×9 得到72 个100。由于不急于处理进 位,所以835×9 算完后,aResult 如下:
b[j++]=str2[i]-'பைடு நூலகம்'; for(i=0; i<len2; i++)//用第二个数乘以第一个数,每次一位
for(j=0; j<len1; j++) c[i+j]+= b[i]*a[j]; //先乘起来,后面统一进位
超大数的四则运算
各类型的范围
❖int (16位) -32768~32767 (注:现在大多数的编译器的int型是32位的 也就
是说跟long型的大小一样) ❖long long或__int64(64位)
-9223372036854775808~ 9223372036854775807 ❖float(32位) 精确到小数点后6~7位 ❖double (64位) 精确到小数点后15~16位 (注:平时做题时 都把浮点型数据定义为double 型 避免精度不够出错)
num1[j++] = s1[i] - '0'; for (i = len2-1,j = 0; i >= 0; i --)
num2[j++] = s2[i] - '0'; for (i = 0; i < M; i ++) {
num1[i] += num2[i]; if (num1[i] > 9) {
for(i=0; i<MAX*2; i++)//循环统一处理进位问题 if(c[i]>=10) { c[i+1]+=c[i]/10; c[i]%=10; }
for(i=MAX*2; (c[i]==0)&&(i>=0); i--);//跳过高位的0 if(i>=0)
for(; i>=0; i--) printf("%d", c[i]);
num1[i] -= 10; num1[i+1] ++; } }
for (i = M-1; (i >= 0)&&(num1[i] == 0); i --) ;//找到第一个不是 0的数的位置
if (i >= 0) //从高位到低位输出每个数 for (; i >= 0; i --) printf ("%d",num1[i]);
else printf ("0\n");
}
减法运算的实现
❖算法也是从低位开始减。先要判断减数和被减 数那一个位数长,减数位数长是正常减;被减 数位数长,则被减数减减数,最后还要加上负 号;两数位数长度相等时,最好比那一个数字 大,否则负号处理会很繁琐;处理每一项时要 ,如果前一位相减有借位,就先减去上一位的 借位,无则不减,再去判断是否能够减开被减 数,如果减不开,就要借位后再去减,同时置 借位为1,否则置借位为0。
主要内容
1
数字存储的实现
2
加法运算的实现
3
减法运算的实现
4
乘法运算的实现
5
除法运算的实现
6
幂运算的实现
数字存储的实现
❖大数计算的因数和结果精度一般是少则数 十位,多则几万位。在C/C++语言中定义 的类型中精度最多只有二十多位。一般我 们称这种基本数据类型无法表示的整数为 大整数。如何表示和存放大整数呢?基本 的思想就是:用数组存放和表示大整数。 一个数组元素,存放大整数中的一位。
❖ans[i+j] = a[i]*b[j];
处理中注意问题:
另外进位时要处理,当前的值加 1 上进位的值再看本位数字是否又
有进位;前导清零。
大数乘法
void Multi(char str1[],char str2[]) {
int len1,len2,i,j; int a[MAX+10],b[MAX+10],c[MAX*2+10]; memset (a,0,sizeof(a)); memset (b,0,sizeof(b)); memset (c,0,sizeof(c)); len1=strlen(str1); for(j=0,i=len1-1; i>=0; i--)//把数字倒过来
比如:1664434318
下标 0 1 2 3 4 5 6 7 8 9 1664434318
加法运算的实现
+加数 9 9 8 7 6 5 4 3 2 0 被加数 1 6 6 4 4 3 4 3 0 0 0 1、进位为1 初始化进位为0,各对应 6 2、进位为1 位相加后再加上进位数 5 3、进位为1 2 4、进位为1
减法运算的实现
- 减数 7 6 8 7 6 5 4 3 2 0 被减数 8 9 7 5 4 3 4 3 2 0
9 1、借位为1 初始化借位为0,各对应 6 2、借位为1 位相减后再减上借位数 0 3、借位为0 2 4、借位为0
由低位向高位相加计算,直至所有运算结束
处理中注意问题:
如果被减数大于减数时 1 ,交换两个数再相减,
else printf("0");
pritnf("\n"); }
除法运算的实现
❖首先说一下我们所要的结果,当除数除 不开被子除数时,不用除到小数,当除 数小于被除数时,除数作为余数既可, 不用再向下除了。
基本思路
❖ 基本的思想是反复做减法,看看从被除数里最多 能减去多少个除数,商就是多少。一个一个减显 然太慢,如何减得更快一些呢?以7546 除以 23 为例来看一下:开始商为0。先减去23 的 100 倍,就是2300,发现够减3 次,余下646 。于是商的值就增加300。然后用646减去230 ,发现够减2 次,余下186,于是商的值增加 20。最后用186 减去23,够减8 次,因此最终 商就是328。
最后加个“-”号即可
结果可能会出现前面是 2 一堆0的情况,要处理好
,如当减数为112,而被 减数为111时,会出现 001
乘法运算的实现
❖首先说一下乘法计算的算法,从低位向高 位乘,在竖式计算中,我们是将乘数第一 位与被乘数的每一位相乘,记录结果,之 后,用第二位相乘,记录结果并且左移一 位,以此类推,直到计算完最后一位,再 将各项结果相加。得出最后结果。
请计算: 1、 2 的 1000次幂 2、 2 的 10000次幂 3、 1234567890123456789123456789034 53434534534535345434543
乘上 9387429387492873492873402803482 0938479288374892733453453534
2. 接下来算4×5。此处4×5 的结果代表20 个10, 因此要 aResult[1]+=20,变为:
1. 再下来算4×3。此处4×3 的结果代表12 个 100,因此要 aResult[2]+= 12,变为:
2. 最后算 4×8。此处4×8 的结果代表 32 个 1000,因此要 aResult[3]+= 32,变为:
1. 乘法过程完毕。接下来从 aResult[0]开始向高 位逐位处理进位问题。aResult[0]留下5,把4 加到aResult[1]上,aResult[1]变为51 后,应 留下1,把5 加到aResult[2]上……最终使得 aResult 里的每个元素都是1 位数,结果就算出 来了:
❖总结一个规律:即一个数的第i 位和另一个数的第j 位相乘所得的数,一定是要累加到结果的第i+j 位上。这里i, j 都是从右往左,从0 开始数。
由低位向高位相加计算,直至所有运算结束
理中注意问题:
1. 判断最后数组的长度. 2. 去掉前导零
大数加法
void Add(char s1[],char s2[])//参数为两个字符串数组 {
int num1[M],num2[M]; int i,j; len1 = strlen (s1); len2 = strlen (s2); for (i = len1-1,j = 0; i >= 0; i --)//num1[0]保存的是低位
大数除法
幂运算的实现
❖幂的实现是最为简单的了,国为有了前面 的算法做铺垫,就是调用乘法函数,来循 环去自乘,幂指数相应减1,直到幂指数变 为0时结束。
❖ 计算的过程基本上和小学生列竖式做乘法相同。 为编程方便,并不急于处理进位,而将进位问题 留待最后统一处理。
❖ans[i+j] = a[i]*b[j];
现以 835×49 为例来说明程序的计算过。
1. 先算835×9。5×9 得到45 个1,3×9 得到27 个10,8×9 得到72 个100。由于不急于处理进 位,所以835×9 算完后,aResult 如下: