北京网站建设报价榆林做网站公司
北京网站建设报价,榆林做网站公司,wordpress指定文章登陆,免费模板网站知乎高精度前言
C中int不能超过2^31-1#xff0c;最长的long long也不能超过2^63-1,所以我们在题目中如果碰到了很长很长的数#xff0c;并且需要进行大数运算时#xff0c;就需要高精度存储。
高精度总体思路
由于int和long long的限制#xff0c;我们要想存放很长的数就需…高精度前言
C中int不能超过2^31-1最长的long long也不能超过2^63-1,所以我们在题目中如果碰到了很长很长的数并且需要进行大数运算时就需要高精度存储。
高精度总体思路
由于int和long long的限制我们要想存放很长的数就需要利用数组存储,C中可以利用STL中的vector容器存储
读取 由于数据很大用int存放不下一般利用字符串读取
数据存放用vector倒序存储即将小位放到前面将大位放到后面,这样方便数据处理
高精度算法
高精度加法
示例题目 我们一般习惯是加法从个位数开始运算 t表示进位初始t为0。先将个位数相加图中为6511
在加法中11%10 1为个位11/101为进位即t 1所以十位数相加为2417如此往复。根据此思路即可写出代码
//高精度加法
#includeiostream
using namespace std;
#includevectorvectorint add(vectorint A,vectorint B)
{//进位t初始为0int t 0;vectorint C;//i到任意一方结尾停止for(int i 0;iA.size() || i B.size();i){if(iA.size() ) tA[i];if(i B.size()) tB[i];//相加后如果大于10要取余作为个位如果小于10不影响C.push_back(t%10);//算进位t t/10;}//最后一次计算 如果t为1 要在最高位补1if(t) C.push_back(t);return C;
}int main()
{vectorint A,B;//利用字符串读取string a,b;cinab;//将高位存放在后面低位存放的前面for(int i a.size()-1;i0;i--) A.push_back(a[i]-0);for(int i b.size()-1;i0;i--) B.push_back(b[i]-0);//auto为自动判断类型会自动判断函数的返回类型auto C add(A,B);for(int i C.size()-1;i0;i--) coutC[i];
}
其中a[i]-0是将字符类型的数字转换为整型类型的数字
需要注意的是这段代码
if(t) C.push_back(t);
这为了解决5050 100类似的情况最后一次计算后如果t1则需要在最高位补1。
高精度减法
示例题目 减法计算思路与加法相似 此时t表示的是借位总体计算公式为 a[i]-b[i]-借位。
借位的计算 如果这次的A[i]-B[i] 0则下次的借位为0反之下次计算的借位为1。
解决了计算的问题减法还有负数的问题如果小数减去大数要为负数所以我们需要自己写一个判断两数大小的函数
bool cmp(vectorint A,vectorint B)
{if(A.size() ! B.size()) return A.size()B.size();for(int i A.size()-1;i0;i--){if(A[i] ! B[i]) return A[i]B[i];}return true;
} 先比较两数的位数再依次比较两数的每一位到最后还未得出结果则返回true表示两数相等
在输出时分类讨论负数先输出负号在输出数据即可
完整代码
//高精度减法模板
#includeiostream
using namespace std;
#includevector
bool cmp(vectorint A,vectorint B)
{if(A.size() ! B.size()) return A.size()B.size();for(int i A.size()-1;i0;i--){if(A[i] ! B[i]) return A[i]B[i];}return true;
}vectorint sub(vectorint A,vectorint B)
{vectorint C;for(int i0,t0;iA.size();i){t A[i] -t;if(iB.size()) t-B[i];C.push_back((t10)%10);if(t0) t1;else t0;}//去除前导0while(C.size()1 C.back() 0 ) C.pop_back();return C;
}int main()
{string a,b;vectorint A,B;cinab;for(int i a.size()-1;i0;i--) A.push_back(a[i]-0);for(int i b.size()-1;i0;i--) B.push_back(b[i]-0);//正数if(cmp(A,B)){auto C sub(A,B);for(int i C.size()-1;i0;i--) coutC[i];}//负数else{auto C sub(B,A);cout-;for(int i C.size()-1;i0;i--) coutC[i];}return 0;
}
在题目中可能会出现需要去除前导0的情况 例如输出023,这个0没有实际意义,需要去除被称为前导0
利用下面这段代码即可去除前导0 while(C.size()1 C.back() 0 ) C.pop_back();
高精度乘法
示例题目 高精度乘法一般只考虑大数乘以小数 与加法十分类似所以具体思路参考加法需要注意的是乘法也需要去前导0.
#includeiostream
using namespace std;
#includevectorvectorint mul(vectorint A,int b)
{vectorint C;int t 0;for(int i 0;iA.size();i) {if(iA.size()) t A[i]*b;C.push_back(t%10);t t/10;}while(C.size() 1 C.back() 0) C.pop_back();return C;
}int main()
{string a;int b;vectorint A;cinab;for(int i a.size()-1;i0;i--) A.push_back(a[i]-0);auto C mul(A,b);for(int i C.size()-1;i0;i--) coutC[i];return 0;
}
高精度除法
实例题目 高精度除法需要注意的是余数并且与加减乘法不同的是除法是从高位开始计算的而加减乘法是从低位开始计算的需要加以区别 模拟除法过程我们可以发现每次的被除数是上次计算得到的余数r*10加上a[i]在图中为
1*10515我们将r/b入数组即可。
完整代码
#includeiostream
using namespace std;
#includevector
#includealgorithmvectorint div(vectorint A,int b,int r)//r传入r的地址便于直接对余数r进行修改
{r 0;vectorint C;for(int i A.size()-1;i0;i--)//对A从最高位开始处理{r r*10A[i];//对A从最高位开始处理C.push_back(r/b);//将上次的余数*10在加上当前位的数字便是该位需要除的被除数r r%b;//余数}//由于在除法运算中高位到低位运算因此C的前导零都在vector的前面而不是尾部vector只有删除最后一个数字pop_back是常数复杂度而对于删除第一位没有相应的库函数可以使用而且删除第一位其余位也要前移//因此我们将C翻转这样0就位于数组尾部可以使用pop函数删除前导0reverse(C.begin(),C.end());while(C.size()1 C.back() 0 ) C.pop_back();return C;
}
int main()
{string a;int b;cinab;vectorint A;for(int i a.size()-1;i0;i--) A.push_back(a[i]-0);int r;auto C div(A,b,r);for(int i C.size()-1;i0;i--) coutC[i];coutendlrendl;
}
高精度除法同样需要去除前导0不过不同的是由于在除法运算中高位到低位运算因此C的前导零都在vector的前面而不是尾部vector只有删除最后一个数字pop_back是常数复杂度而对于删除第一位没有相应的库函数可以使用而且删除第一位其余位也要前移因此我们可以利用reverse()函数将C翻转这样0就位于数组尾部可以使用pop函数删除前导0 此篇为学习之余的总结作为笔记使用如果有错误还请指正谢谢
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/90719.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!