高精度运算板子(C++实现)

参考:

洛谷《深入浅出程序设计竞赛》

高精度算法全套(加,减,乘,除,全网最详细)_哔哩哔哩_bilibili

高精度运算

为什么使用高精度

int为10^9^数量级

long long为10^18^数量级

当数据范围超过long long 最高限,我们使用高精度运算。

高精度加法

高精度加法较为简单

使用数组模拟

为了避免正序边界不同,我们把两个数组倒序放入数组

最后删除前导0后倒序输出

计算过程中注意进位的实现即可

 #include<bits/stdc++.h>
 //高精度加法
 #define maxn 520
 using namespace std;
 int a[maxn], b[maxn], c[maxn];
 int main() {
     string A, B;
     cin >> A >> B;
     int len = max(A.length(), B.length());
     for (int i = A.length() - 1, j = 1; i >= 0; i--, j++)
         a[j] = A[i] - '0';
     for (int i = B.length() - 1, j = 1; i >= 0; i--, j++)
         b[j] = B[i] - '0';
     for (int i = 1; i <= len; i++) {
         c[i] += a[i] + b[i];
         c[i + 1] = c[i] / 10;
         c[i] %= 10;
     }
     if (c[len + 1])
         len++;
     for (int i = len; i >= 1; i--)
         cout << c[i];
 }

高精度减法

高精度减法要考虑如下问题:

  1. 减数与被减数的大小关系:前置判断进行交换保证大减小

  2. 如果交换了最后要输出负号

  3. 0的特判(参照洛谷题解)

#include<bits/stdc++.h>
 //高精度减法
 ​
 using namespace std;
 const int  maxn =  10500;
 int a[maxn], b[maxn], c[maxn]; //计算数组
 int main() {
     string A, B; //存储数组
     cin >>  A >> B;
     bool flag = 0; //负号标记
 ​
     if ((A < B && A.size() == B.size()) || A.size() < B.size())
     //前置判断 永远让大的减小的
     {
         swap(A, B);
         flag = 1; //如果交换了我们最后要输出一个负号!
     }
     //如果有交换操作 就尽量别用int lena = A.length()了 
     int len = max(A.size(), B.size());
 ​
     for (int i = A.size(); i > 0; i--)
         a[i] = A[A.size() - i] - '0';
     for (int i = B.size(); i > 0; i--)
         b[i] = B[B.size() - i] - '0';
     // 将字符串中的信息转化到数组中,数组模拟数字
 ​
     for(int i = 1; i <= len; i ++)
     {
         if(a[i] < b[i])
         {
             a[i + 1] --;
             a[i] += 10;
         }
         c[i] = a[i] - b[i];
     }
 ​
     while (c[len] == 0) //减法不存在进位情况 这里删除前导0
         len--;
 ​
     if (flag) //输出负号
         cout << "-";
 ​
     for (int i = len; i > 0; i--)
         cout << c[i];
     if(len < 1) //0特判
         cout << '0';
     cout << endl;
     return 0;
 }

高精度乘法

经过了加法和减法的代码编写,乘法道理相同,也就是对竖式乘法进行手工模拟,重点是代码18-20行的贡献计算,别的在此不再赘述。

 #include<bits/stdc++.h>
 //高精度乘法
 const int maxn = 5010;
 using namespace std;
 ​
 int a[maxn], b[maxn], c[maxn];
 ​
 int main() {
     string A, B;
     cin >> A >> B;
     int lena = A.length();
     int lenb = B.length();
     int len = lena + lenb; //乘积的位数不超过两数的位数之和
     for (int i = lena - 1; i >= 0; i--)
         a[lena - i] = A[i] - '0';
     for (int i = lenb - 1; i >= 0; i--)
         b[lenb - i] = B[i] - '0';
     for (int i = 1; i <= lena; i++)
         for (int j = 1; j <= lenb; j++)
             c[i + j - 1] += a[i] * b[j]; //计算贡献
     for (int i = 1; i <= len; i++)
     {
         c[i + 1] += c[i] / 10;
         c[i] %= 10; //进位
     }
     while(!c[len])  //去除前导0
          len--; 
 ​
     for (int i = max(1, len); i >= 1; i--)
         cout << c[i];
     cout << endl;
     return 0;
 }
 ​

高精度除法

高精度除以低精度

使用逐位试商法

具体见代码注释

#include<bits/stdc++.h>
 //高精度除以低精度
 const int maxn = 5005;
 using namespace std;
 ​
 string s;
 long long a[maxn], b, c[maxn], x;
 int main()
 {
     cin >> s >> b;
     int lena = s.length();
     for (int i = 1; i <= lena; i++)
         a[i] = s[i - 1] - '0';
     //将被除数用数组储存
     for (int i = 1; i <= lena; i++)
     {
         c[i] = (x * 10 + a[i]) / b;
         x = (x * 10 + a[i]) % b;
     }/*
     接下来的部分和高精度加减乘法不太一样
     原因是只有除法没有使用倒序而是使用正序
     */
     int lenc = 1;
     while (c[lenc] == 0 && lenc < lena)
         lenc++; //在除式上方从左至右扫描一遍忽略前导0
 ​
     for (int i = lenc; i <= lena; i++)
         cout << c[i];
     //cout << ' ' << x << endl; //输出余数
     return 0;
 }
 ​
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值