高精度运算总结(10.21更新整数乘法)
来源:互联网 发布:java ocx 编辑:程序博客网 时间:2024/04/28 18:34
首先抛出问题,给定两个几十万位的数,输出他们加减乘除的运算结果。
分析:对于这类问题,不要指望int double这些东西了,基本数据类型不可能存的下。我们可以把这两个数当成字符串输入到数组中,然后模拟手动的竖式运算(不会的话,回去上小学)得出结果。
应用:随便什么工程计算要求精确到小数点后十万位,或者运算数直接就有十万位,这些情况太常见了吧。貌似windows的计算器就是采用高精度运算,不信去试试。
暂定的写作顺序如下
整数加法(完事)
整数减法
整数乘法(完事)
整数除法
小数加法
小数减法
小数乘法
小数除法
整数加法
给定两个数989和9889来模拟一下大整数加法的实现过程(请先手动做一下竖式计算)
- 接收数据并预处理
char str_1[100]; char str_2[100]; memset(str_1,'\0',sizeof(str_1));//初始化字符串为空 memset(str_2,'\0',sizeof(str_2)); scanf("%s%s",str_1,str_2);//字符串形式接收两个数 int len_1=strlen(str_1); int len_2=strlen(str_2); int num_1[100];//两个数倒序装入整型数组准备运算 int num_2[100];//为什么要倒叙?为了给进位留足空间 memset(num_1,0,sizeof(num_1)); memset(num_2,0,sizeof(num_2)); for(int i=0; i<len_1; i++) num_1[len_1-i-1]=str_1[i]-'0'; for(int i=0; i<len_2; i++) num_2[len_2-i-1]=str_2[i]-'0';
为什么用字符串数组接收数据又转存到整型数组?
整型数组接收单个数字是以空格或者回车作为结束符,大整数的输入过程是没有空格或回车的。
字符串数组实际存储的是一个字符对应的Ascll码值,9+8其实是9对应的Ascll码和8对应的Ascll码相加得到新的Ascll码,结果肯定不是17,因为Ascll码表中只有0~9。
为什么要倒叙转存进整型数组?
要留足进位空间。假如是正序存入的(括号内写数组下标)
9(0)8(1)9(2)+
9(0)8(1)8(2)9(3)
我们该如何使得这两个数的个位对齐呢?就算个位对齐成这种样子
9(1)8(2)9(3)+
9(0)8(1)8(2)9(3)
得到的结果也会因为进位而无法存储
1(-1)0(0)8(1)7(2)8(3) 数组下标怎么可能为-1
如果我们是倒叙转存进整型数组的话,一切问题都可以迎刃而解
9(0)8(1)9(2) +
9(0)8(1)8(2)9(3)
8(0)7(1)8(2)0(3)1(4)
不仅个位对齐,由于全部是倒叙,向右进位也可以很好的解决。
2.运算并处理进位
int num[100];//存储运算结果 memset(num,0,sizeof(num)); int len=max(len_1,len_2);//运算结果的长度 for(int i=0; i<len; i++) { num[i]=num_1[i]+num_2[i]+num[i];//num[i]中可能存有前一位的进位 if(num[i]>=10)//如果需要进位 { num[i]=num[i]-10; num[i+1]++;//进位 } }
3.去除前导零并输出
while(num[len]==0)//去除前导零 len--; for(; len>=0; len--) printf("%d",num[len]);
整数乘法
给定9999*999模拟一下
接收数据并预处理
char str_1[maxn];//接收数据char str_2[maxn];int num_1[maxn];//预处理结果int num_2[maxn];int num[maxn];//最终结果int len_1=strlen(str_1);int len_2=strlen(str_2);memset(num_1,0,sizeof(num_1));memset(num_2,0,sizeof(num_2));memset(num,0,sizeof(num));scanf("%s%s",str_1,str_2)for(int i=len_1-1,j=0; i>=0; i--,j++) //逆序转换存储 num_1[j]=str_1[i]-'0';for(int i=len_2-1,j=0; i>=0; i--,j++) num_2[j]=str_2[i]-'0'; num_2[j]=str_2[i]-'0';
为什么字符串数组接收并逆序转存到整型数组?
请移步上面整数加法学会再来。
模拟手动乘法,由于乘法运算中进位很复杂,我们可以先不处理进位
int len=0;//记录最终结果的长度//两层循环模仿手动乘法for(int i=0; i<len_1; i++){ int flag_len=i;//暂时记录长度 for(int j=0; j<len_2; j++,flag_len++) num[flag_len]=num[flag_len]+num_1[i]*num_2[j]; len=max(len,flag_len);//更新实际长度}
最后处理进位,先处理首位到倒数第二位,最后一位单独处理,因为最后一位可能不仅仅是往前进一位那么简单,而是可能需要进很多位,处理时注意实际长度len的变化
//集中处理进位//先处理首位到倒数第二位for(int i=0; i<len-1; i++) if(num[i]>9) { num[i+1]+=num[i]/10; num[i]=num[i]%10; }//再处理最后一位的进位while(num[len-1]>9){ num[len]+=num[len-1]/10; num[len-1]=num[len-1]%10; len++;}
最后输出结果
for(int i=len-1; i>=0; i--) printf("%d",num[i]);printf("\n");
以上只是提供了一种思路,并且在实现过程中还有很大的时空冗余度可以优化。
- 高精度运算总结(10.21更新整数乘法)
- 大整数运算乘法(高精度运算)
- 高精度(大整数乘法)
- 大整数乘法(高精度)
- 整数高精度运算的库(加法,减法,乘法,除法,取模)
- 整数高精度乘法
- 大整数运算(乘法)
- 大整数运算(乘法)
- 大整数运算(高精度运算)
- 高精度乘法运算的实现(不完全)
- 高精度运算之乘法
- 高精度之乘法运算
- 高精度整数运算
- 高精度整数运算
- 高精度计算-大整数乘法
- 高精度总结(高精度类和重载运算高精度阶乘)
- 超大整数乘法模板(高精度乘以低精度)
- cv3123 高精度练习之超大整数乘法(FFT)
- 百度地图生成API Key 获取Android签名证书的sha1值
- 快速排序最坏的情况啥时候出现?
- 指针和引用
- python for else 循环
- 【codevs 2370】小机房的树
- 高精度运算总结(10.21更新整数乘法)
- TCP三次握手四次回收图解
- android学习语法用法知识点
- 函数调用的四种模式以及this的指向浅析
- C++ 简单的程序--‘hello world’
- Php复习(4)
- conf/masters中masters的内容探究
- 【基础编程】HDOJ2045不容易系列之(3)—— LELE的RPG难题
- js常用正则表达式