高精度之高精度除法(高精除以高精)

2024-03-09 18:32
文章标签 高精度 除以 除法 高精

本文主要是介绍高精度之高精度除法(高精除以高精),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

好像NOIP并不会用到,但是作为强迫症的我还是坚持学了。高精度除以高精度我所知道的有两个思路:

手动模拟法

还是手动模拟除法过程,但是注意在截取了被除数的正确片段之后应该试商,即枚举k从1到9看当k等于多少才合适,但是如果每次循环都试一边的话时间复杂度必定会很高,优化的方法就是在开始时就把k乘以除数的值记录下来,程序执行时只要二分比较确定K值就行了。

但是这种方法实现起来太过麻烦,比较大小时可能会用到高精度减法,刚开始初始化的时候又用到高精度乘法,所以被我自动忽略。下面着重介绍第二种方法。

高精度减法模拟法

第二种方法是运用高精度减法,截取完被除数之后用余数减除数,直到值为负数,这样确定出了这意味的商应该是多少,然后再取被除数的下一位。为了免去一些麻烦,可以使被除数被截取的区间长度比除数大1,最后得出来的商如果大于9就朝上一位进位。具体代码实现如下:
读的过程中建议自己造一组数据自行模拟手动的减法过程

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector> 
#include<iterator>
#include<cstdio>
using namespace std;
string a,b,d="0",bb="0";
int dif,dns=0,r,all=0;
int lena,lenb,qq=0;//qq记录小数点是否已经输出 
vector<int>c;
void change(string x,string y)//这里的减法和我写的独立的减法程序一样,不再赘述
{c.clear();dif=abs(x.length()-y.length());int len=max(x.length(),y.length());for(int i=len-1;i>=0;i--){int a=x[i]-'0'+dns,b=y[i-dif]-'0';if(len-i > y.length()) {b=0;}int p=a-b;dns=0; if (p < 0) {p+=10;dns=-1;}c.push_back(p);}
}
void handle()
{int num=0;while(a.length() > b.length() || (b.length() == a.length() && a >= b)){//只是将除法的过程改为了减法,而这一步就是确定商多少num++;//每减一次商累加一change(a,b);int con=1;a="0";for(int i=c.size()-1;i>=0;i--)//把余数重新转化为string {if(c[i]==0&&con){continue;}con=0;if(a == "0") a=char(c[i]+48);//0的阿斯科玛是48else a=a+char(c[i]+48);}//为了不再更改之前写的高精度减法的基础,这里只能将余数转换成string的形式//之前其实没用char(c[i]+48)的形式但是出现了各种错误,最后才发现这样可以}cout<<num;//输出得到的商的当前位,当然如果希望得到结果的话也可以将它存起来if(a == "0" ) exit(0);//对于小于的情况,如果余数等于0了一定是已经除尽int con=1;while(a.length() < b.length() || (b.length() == a.length() && a < b)){//余数后面补零,使余数大于除数if(con--) a=a+char(48);//如果只补一次,自然结束了else //但是如果补了两个0的话,一定会得到一个商是0,这时应该输出{cout<<"0";a=a+char(48);}}
}
int main()
{cin>>a>>b;if(b=="0"){cout<<"-1";return 0;}lena=a.length();lenb=b.length();if(a == b){cout<<"1";return 0;}if(lena < lenb || (lena == lenb && a < b))//如果被除数小于除数,先输出“0.”,再将被除数加一{cout<<"0.";a+="0";while(a.length() < b.length() || (b.length() == a.length() && a < b))//有可能出现加一后被除数仍然小于除数,这时应该继续加{a+="0";cout<<"0";//为了模拟手动除法,每次给被除数加末尾数字的时候都应该输出0}while(all <= 100)//all用来控制输出的位数,这里是输出的小数点后的位数{handle();//其实这里的handle改自高精度减法的main函数all++;}}else//被除数大于除数和小于除数的情况差别很大,所以分开写{r=lenb-1;//记录a中已经读到的位置//还是模拟除法,每次得到商的一位后都应该从被除数上降下一位到余数,而r就是记录从那里降//之前大于的情况在因为被除数已经没有位可以降,所以是直接降0,而这里显然不可以for(int i=0;i<lenb;i++)//将所选区间转化为string形式 {if(d == "0") d=a[i];else d+=a[i];}while(d.length() < b.length() || (d.length() == b.length() && d < b)) {d+=a[++r];}//还是考虑到可能所选区间不够大while(all <= 100){int num=0;while(d.length()>lenb||(d.length()==lenb && d>=b )){num++;change(d,b);//减法过程int con=1;d=bb;for(int i=c.size()-1;i>=0;i--){if(c[i]==0&&con)continue;con=0;if(d == "0") d=char(c[i]+48);else d=d+char(c[i]+48);}
//              cout<<d<<endl;}cout<<num;if(r+1 == lena && d == "0") break;if(r+1 == lena ){if(!qq){cout<<".";qq=1;}d=d+char(48);}else d=d+a[++r];all++;}}return 0;
}

这篇关于高精度之高精度除法(高精除以高精)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/791582

相关文章

高精度计算(代码加解析,洛谷p1601,p1303)除法待更新

目录 高精度加法 高精度减法 高精度乘法 高精度加法 我们知道在c++语言中任何数据类型都有一定的表示范围。当两个被加数很大时,正常加法不能得到精确解。在小学,我们做加法都采用竖式方法。那么我们也只需要按照加法进位的方式就能得到最终解。 8 5 6+ 2 5 5-------1 1 1 1 加法进位: c[i] = a[i] + b[i];if(c[i] >=

高精度打表-Factoring Large Numbers

求斐波那契数,不打表的话会超时,打表的话普通的高精度开不出来那么大的数组,不如一个int存8位,特殊处理一下,具体看代码 #include<stdio.h>#include<string.h>#define MAX_SIZE 5005#define LEN 150#define to 100000000/*一个int存8位*/int num[MAX_SIZE][LEN];void

高精度计算----减法运算(浮点型)

基于上一贴,修改减法运算适合于高精度浮点型计算。 因为减法比加法难度大一点,考虑的地方也要多一些,可能代码有欠缺,欢迎指出。 运算说明: 1、相减函数依旧没改变,包括上一贴的判断被减数与减数的大小函数也没变。 2、增加两个函数,取小数位数函数和结果处理(回归小数点)函数 3、与加法浮点高精度运算相比,这里改变较多的是结果处理函数,加法加完后,位数不减反增,而且最多增一位。减法会消失掉好多

高精度计算----减法运算

处理大数减法运算: 1、首先要判断被减数与减数哪个更大,再相应的带入减法函数去处理。具体的比较可以使用字符串的相关知识去比较。 2、相减要先对齐数组,依照减数的长度,执行相应的减法运算次数。 3、不需要借位相减的话,直接减去;需要的话,向前借一位,若前一位是0,则再前借(此时前一位的0变为10)。 测试程序效果如下:   以下代码包括相减函数,比较被减数减数函数,若有错误,请指出:

高精度加法,乘法,阶乘

#include <iostream>#include <map>#include <string>#include <algorithm>using namespace std;const int Max = 50000;string str1,str2;/***********乘法***********/void chenfa(){cin >> str1>>str2;int a

高精度治具加工的重要性和创新性

在现代制造业中,高精度治具加工扮演着至关重要的角色。它不仅是生产过程中的关键环节,更是推动行业不断创新和发展的重要力量。时利和将解析高精度治具加工的重要性和创新性。   一、高精度治具加工的重要性   1.确保产品质量   高精度治具能够为生产过程提供准确的定位、夹紧和导向功能,从而确保产品的尺寸精度、形状精度和表面质量。例如,在电子制造领域,高精度的治具可以保证芯片的精确安装,提高电子

信息学奥赛初赛天天练-83-NOIP2014普及组-基础题2-输入设备、输出设备、操作系统、二进制、整数除法、while、do while循环

1 NOIP 2014 普及组 基础题2 4 以下哪一种设备属于输出设备( ) A 扫描仪 B 键盘 C 鼠标 D 打印机 5 下列对操作系统功能的描述最为完整的是( ) A 负责外设与主机之间的信息交换 B 负责诊断机器的故障 C 控制和管理计算机系统的各种硬件和软件资源的使用 D 将没有程序编译成目标程序 11 下列各无符号十进制整数中,能用八位二进制表示的数中最大的是( ) A 296

【HDU】4927 Series 1 高精度

传送门:【HDU】4927 Series 1 题目分析:公式很好推,到最后就是C(n-1,0)*a[n]-C(n-1,1)*a[n-1]+C(n-1,2)*a[n-2]+...+C(n-1,n-1)*a[n]。 用C(n,k)=C(n,k-1)*(n-k+1)/k即可快速得到一行的二项式系数。 我看JAVA不到1000B 15分钟就能过。。。我又敲了大数模板然后将近2个小时才过T U

高精度加、减、乘、除(高精除以低精)

高精度加法 法1:P1601 A+B Problem(高精) #include <bits/stdc++.h>using namespace std;char s1[510], s2[510];int a[510], b[510], sum[510];int lena, lenb, lens;int main(){cin >> s1 >> s2;lena=strlen(s1);le

【高精度】-DLUTOJ-1176-大数乘法

题目链接:http://acm.dlut.edu.cn/problem.php?id=1176 题目描述:赤裸的大数乘法 解题思路: 突然想到自己没写过高精度乘法,就回咱们自己OJ上找出了这道题,赤裸的高精度乘法而已,没想到依然觉得不好写,准确说来是我从小到大算乘法的习惯使我产生了错觉:“ 想写大数乘法就得先写一个大数加法出来 ”。喂!我短路了半天才想明白,int 数组里可以存个两位数啊,再