高精度
定位
Java和Python不用;
高精度在面试中不常考,但是在笔试容易出;
加减要求位数在1e6;
乘法大的那个数位数要小于1e6,小的数要小于1e9或1万;
除法和大乘大就有点变态了;
高精度加法
本质上就是人类使用的加法用计算机表示,每个数字用数组存储
#include<iostream>
#include<vector>
using namespace std;
const int N = 1e6 + 10;//额外+10防止出现边界问题
int arr[N] = { 0 };
vector<int>add(vector<int>& A, vector<int>& B)//用数组来表示的整数A与B,返回的和也用数组表示;
{
vector<int>C;//C为和;
int t = 0;//t为进位;
for (int i = 0; i < A.size() || i < B.size(); i++)
{
if (i < A.size())//如果A在该位有值
{
t += A[i];//t+A在该位的值
}
if (i < B.size())//如果B在该位有值
{
t += B[i];//t+B在该位的值
}
C.push_back(t % 10);//得到这一位的和;
t /= 10;//是否需要进位;
}
if (t)//如果t在第一位进位了
{
C.push_back(1);//则下一位补上一个1;
}
return C;
}
int main()
{
string a, b;
vector<int>A, B;
cin >> a >> b;//若a为123456
for (int i = a.size() - 1; i >= 0; i--)
{
A.push_back(a[i] - '0');//存储数字,因为a[i]为一个字符数字,要把它转换为数字需要对一个数字进行运算,a对应的A为{6,5,4,3,2,1}
}
for (int i = b.size() - 1; i >= 0; i--)//同理
{
B.push_back(b[i] - '0');
}
auto C = add(A, B);
for (int i = C.size() - 1; i >= 0; i--)
{
printf("%d", C[i]);//从数组高位往数组低位打印,得到从个位到最高位的数;
}
return 0;
}
高精度减法
1)判断结果正负;
2)借位;
bool cmp(vector<int>& A, vector<int>& B)//这里不能用strcmp,它无法比较位数;
{
if (A.size() != B. size())
{
return A.size() > B.size();
}
for (int i = A.size() - 1; i >= 0; i--)
{
if (A[i] != B[i])
{
return A[i] > B[i];
}
}
return true;
}
vector<int>sub(vector<int>& A, vector<int>& B)
{
vector<int>C;
int t = 0;
for (int i = 0; i < A.size(); i++)//主函数里保证了左边的变量大于右边的变量;
{
t = A[i] - t;
if (i < B.size())//判断B在该位是不是存在,如果存在再减去;
{
t -= B[i];
}
C.push_back((t + 10) % 10);//若t>=0,则(t+10)%10就是t的本身,若t<0,则(t+10)%10就是t借位后的值;
if (t < 0)
{
t = 1;//借位,然后下一位运算会额外减1;
}
else
{
t = 0;
}
}
while (C.size() > 1 && C.back() == 0)//若位数大于1,且最后一位为0;
{
C.pop_back();//去掉最后一位,也就是先导0;eg:120-119=001,该函数就是为了去掉0;
}
return C;
}
int main()
{
string a, b;
vector<int>A, B;
cin >> a >> b;//若a为123456
for (int i = a.size() - 1; i >= 0; i--)
{
A.push_back(a[i] - '0');//存储数字,则A为{6,5,4,3,2,1}
}
for (int i = b.size() - 1; i >= 0; i--)//同理
{
B.push_back(b[i] - '0');
}
if (cmp(A, B))//比较A,B的大小,如果A>B;
{
auto C = sub(A, B);
for (int i = C.size() - 1; i >= 0; i--)
{
printf("%d", C[i]);//从数组高位往数组低位打印,得到从个位到最高位的数;
}
}
else//如果B>A,则需要输出负数;
{
auto C = sub(B, A);
printf("-");
for (int i = C.size() - 1; i >= 0; i--)
{
printf("%d", C[i]);//从数组高位往数组低位打印,得到从个位到最高位的数;
}
}
return 0;
}
高精度乘法_大乘小
1)每一位的结果都是(Ab+上一位的进位)%10;
2)进的位是(Ab+上一位的进位)/10;
3)大数的每一位都去乘小数(不是小数的每一位);
vector<int>mul(vector<int>& A, int b)
{
vector<int>C;
int t = 0;//进位
for (int i = 0; i < A.size() || t; i++)//要不就是i循环完A,要不就是t被处理完;
{
if (i < A.size())
{
t += A[i] * b;//如果A还没使用完所有位数;
}
C.push_back(t % 10);//每一位的结果都是(A*b+上一位的进位)%10;
t /= 10;//进的位是(A*b+上一位的进位)/10;
}
return C;
}
int main()
{
string a;
int b;//高精度a*低精度b;
cin >> a >> b;
vector<int>A;
for (int i = a.size() - 1; i >= 0; i--)
{
A.push_back(a[i] - '0');
}
auto C = mul(A, b);
if(b == 0)
{
printf("0");
}
else
{
for (int i = C.size() - 1; i >= 0; i--)
{
printf("%d", C[i]);
}
}
return 0;
}
高精度乘法_高精乘高精
#include<bits/stdc++.h>
using namespace std;
char a[10001], b[10001];
int A[10001], B[10001] ,c[10001];
int i, x, len, j;
int main()
{
cin >> a >> b;
int sza = strlen(a);
int szb = strlen(b);
for (i = 1; i <= sza; i++)//反向输入,方便乘
{
A[i] = a[sza - i] - '0';
}
for (i = 1; i <= szb; i++)
{
B[i] = b[szb - i] - '0';
}
for (i = 1; i <= szb; i++)
{
for (j = 1; j <= sza; j++)
{
c[i + j - 1] += A[j] * B[i];//错位乘法
}
}
for (i = 1; i < sza + szb; i++)
{
if (c[i] > 9)
{
c[i + 1] += c[i] / 10;//进位
c[i] %= 10;//留下的一位
}
}
len = sza + szb;
while (c[len] == 0 && len > 1)//去掉前导零
{
len--;
}
for (i = len; i >= 1; i--)
{
cout << c[i];
}
return 0;
}
6.C++pow极致优化n次方
#include<bits/stdc++.h>
using namespace std;
int n;
int main()
{
cin >> n;
cout.precision(0);//删除小数点后的所有的0;
cout << std::fixed << pow(2.0, n);//将高精算数转化为常规;
return 0;
}
7.高精除低精
记得去掉前导零。
#include<bits/stdc++.h>
using namespace std;
vector<int>div(vector<int>&A, int b, int &r)//引用余数,可以直接在函数里修改余数;
{
vector<int>C;//商;
r = 0;//余数;
for (int i = A.size() - 1; i >= 0; i--)//除法从最高位开始除,因此存储的也是最高位
{
r = r * 10 + A[i];//上一位的余数*10+下一位的数字;
C.push_back(r / b);//把商放在C的末尾
r %= b;//得到每一位的余数
}
reverse(C.begin(), C.end());//由于从最高位开始存储,因此需要将最高位和最低位之间所有元素全部倒转;
while (C.size() > 1 && C.back() == 0)
{
C.pop_back();
}
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');
}
int r = 0;
auto C = div(A, b, r);
for (int i = C.size() - 1; i >= 0; i--)
{
printf("%d", C[i]);
}
printf("\n");
printf("%d", r);
return 0;
}

浙公网安备 33010602011771号