高精度乘法
A 1 2 3
B × 1 2
______________________
C3 C2 C1 C0
C0 == (3 × 12) % 10 == 6
t1 == (3 × 12) / 10 == 3,12 * 3 == 36 需要进位 3
C1 == (2 × 12 + 3) % 10 == 7
t2 == (2 × 12 + 3) / 10 == 2
C2 == (1 × 12 + 2) % 10 == 4
t3 == (1 × 12 + 2) / 10 == 1
C3 == 1
123 × 12 == 1476
把 B 看成一个整体和 A 去乘,不是和普通的乘法一样一位一位相乘
为什么整除 10 是进位?
C3C2C1C0 == C3 * 10^3 +C2 * 10^2 + C1 * 10^1 + C0 *10^0
A5 A4 A3 A2 A1 A0
× b
————————————————
C1 C0
个位:C0 == A0 × b %10
进位:t == A0 × b / 10
十位:C1 ==(A1 × b + t (上一位的进位) ) % 10 == A1 × b %10 + t %10
再往前进位:C1(A1 × b + t) % 10 / 10
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
//C = A * b
vector<int> mul(vector<int> &A,int b)
{
//存储结果
vector<int> C;
//进位-> 第0位的进位是0
int t = 0;
//i没有循环完 或 进位没有处理完t != 0
for(int i = 0;i < A.size()||t;i++)
{
//判断i是否在A的范围里-> 当前位的值
if(i<A.size()) t += A[i]*b;
//当前位的结果
C.push_back(t%10);
//下一位的上一位的进位-> 这个数往前移动一位-> 有很多种情况
t/=10;
}
return C;
}
int main()
{
string a;
int b;
cin >> a >> b;
vector<int> A;
for(int i = a.size()-1;i>=0;i--) A.push_back(a[i] - '0');
vector<int> C = mul(A,b);
for(int i = C.size()-1;i>=0;i--) printf("%d",C[i]);
return 0;
}
高精度除法
高精度整数 / 低精度整数
从第 0 位开始看
0 1 1 2
___________
1 1 / 1 2 3 4
0
——————
1 2 最高位不够,商为 1 / 11 == 0,余数1为 1 % 11 == 1,余数2为 1 % 11 == 1 × 10 + 下一位的数字 2 == 12
1 1 下一位: 商为 12 / 11 == 1, 余数3为 12 % 11 == 1
——————
1 3 余数4为 (余数3为1) × 10 + 下一位的数字 3 == 13
1 1 . . .
——————
2 4
2 2
————
2
C3 C2 C1 C0
_______________
b / A3 A2 A1 A0
r = A3 商为 C3 == A3 / b == 0,余数1为 r == A3 - b × C3 == A3 % b == r '
——————
r ' × 10 + A2 余数2 == 余数1 r ' × 10 + 下一位的数字 A2 → 前两位的余数
C2 前两位的余数r ' / b == 商 C2 . . . . . 余数3 r ' ' == r ' % b
r ' '
r ' ' × 10 + A1
——————
r ' ' ' × 10 + A0
——————
r ' ' ' ' . . .
除法返回商和余数,除法从最高位开始计算,加、减、乘法都是从最低位开始算,如果题目中只有除法,可以选择正向存储
一般题目中加减乘除混合,所以还是选择逆序存储
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
//C = A / b 商C 余r
vector<int> div(vector<int> &A,int b,int &r)
{
//商
vector<int> C;
//余数
r = 0;
//从最高位开始看
for(int i = A.size()-1;i >= 0;i--)
//余数 == 余数 * 10 + 当前位
r = r * 10 + A[i];
//当前位的商
C.push_back(r/b);
//余数
r %= b;
//C[0]存储最高位,C[1]存储次高位
reverse(C.begin(),C.end());
//去掉前导0
while(C.size()>1 && C.back() == 0) C.pop_back();
return C;
}
int main()
{
string a;
int b;
cin >> a >> b;
vector<int> A;
int r;
for(int i = a.size()-1;i>=0;i--) A.push_back(a[i] - '0');
vector<int> C = div(A,b,r);
for(int i = C.size()-1;i>=0;i--) printf("%d",C[i]);
cout << endl << r << endl;
return 0;
}