娄底市网站建设_网站建设公司_RESTful_seo优化
2025/12/30 20:32:17 网站建设 项目流程

这东西暂且归为数据结构吧

巨难写的东西,恶心死个人。(但用还是要用的
说实话不常用,但是该用的时候还真没有能替代的。

正常C++,int类型最大长度为9位,longlong约为18位,就算是__int128也不过30多位
而有的时候,我们需要用到几百上千位,这时候就得用到高精度了。
它的中心思想是用字符串存下数,利用字符串模拟加减乘数的运算
但时代在进步,现在好像都用vector来存储大整数。

注意,高精度有一种缩短时间和空间的方法,叫压位,正常我们每个int只存1位数,但这样太浪费了,都知道int最大是9位,那么我们就让int存9位,这样就缩小了时间和空间。一般压8位而不压9位,为了防止以外爆炸,对于高精乘低精则更低

读入

一般利用字符串读入,然后用vector存起来。
注意一般是逆序转存,因为我们操作的时候是从最低位开始的

非压位

void read(string &s1, vector<int> &A)
{for (int i = s1.size() - 1; i >= 0; i -- ) A.push_back(s1[i] - '0');
}

压位版

这玩意看看代码应该就明白了。
注意一点j == 9那里压多少位写多大的数

void read(string &s1, vector<int> &A)
{for (int i = s1.size() - 1, t = 1, s = 0, j = 0; i >= 0; i -- ){s += (s1[i] - '0') * t;j ++ , t *= 10;if (j == 9 || i == 0) {A.push_back(s);s = j = 0;t = 1;}}
}

输出

注意逆序输入就要逆序输出

非压位

for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];

压位

压位版因为C的首位不确定长度所以要先输出来,
而在后面可能会遇到因取模而小于压位位数的情况,所以我们要用printf固定输出,空缺补0

cout << C.back();
for (int i = C.size() - 2; i >= 0; i -- ) printf("%09d", C.[i]);

高精加

高精加有两种,一种为高精加高精,一种为高精加低精,但是高精加低精更少用,所以这里只写高精乘高精。

注意不能存负数,鬼才想处理正负号

非压位和压位几乎没有区别,实质上都是压位版,只不过压1位就是不压而已。

非压位

vector<int> M_add(vector<int> A, vector<int> B)
{if (A.size() < B.size()) return M_add(B, A);vector<int> C;int t = 0, len = A.size();for (int i = 0; i < len; i ++ ){t += A[i];if (i < B.size()) t += B[i];C.push_back(t % 10);t /= 10;}if (t) C.push_back(t);return C;
}

压位

int base = 1000000000; // 压位数组
vector<int> M_add(vector<int> A, vector<int> B)
{if (A.size() < B.size()) return M_add(B, A);vector<int> C;int t = 0, len = A.size();for (int i = 0; i < len; i ++ ){t += A[i];if (i < B.size()) t += B[i];C.push_back(t % base);t /= base;}if (t) C.push_back(t);return C;
}

高精减

和高精加有所不同,注意不够减了借位。最多借base位

bool cmp(vector<int> A, vector<int> B) // 比较
{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, len = A.size();for (int i = 0; i < len; i ++ ){t = A[i] - t;if (i < B.size()) t -= B[i];C.push_back((t + 10) % 10);if (t < 0) t = 1; // 减下一位的else t = 0;}while (C.back() == 0 && C.size() > 1) C.pop_back();return C;
}int main()
{cin >> s1 >> s2;for (int i = s1.size() - 1; i >= 0; i -- ) A.push_back(s1[i] - '0');for (int i = s2.size() - 1; i >= 0; i -- ) B.push_back(s2[i] - '0');if (cmp(A, B)) C = sub(A, B);else C = sub(B, A), cout << '-';for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];return 0;
}

高精乘

高精乘高精不常用,实际上跟着思路也能写出来,但速度慢,而且难调
兴许哪天脑子用了写个高精除高精

高精乘低精

vector<int> M_mul(vector<int> A, int b)
{vector<int> C;int t = 0, len = A.size();for (int i = 0; i < len || t; i ++ ) // 一定要把t搞干净{if (i < len) t += A[i] * b;C.push_back(t % 10);t /= 10;}while (C.back() == 0 && C.size() > 1) C.pop_back();return C;
}

高精除

高精除低精简单,高精除高精困难,这里说个思路,高精除高精,化除为减是一个办法

vector<int> divi(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];C.push_back(r / b);r %= b;}reverse(C.begin(), C.end()); // C push进去的先是高位后是低位,为了输出的一致所以要逆序while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}

好久以前的高精除高精

#include<iostream>
#include<cstring>
using namespace std;const int N=200010;int a[N],b[N],n,m;
long long sum;
char s1[N],s2[N];bool bol()
{if (n!=m) return n>m;for (int i=1;i<=n;i++) if(a[i]!=b[i]) return a[i]>b[i];return true;
}void cut()
{for (int i=1;i<=n||i<=m;i++){a[i]-=b[i];if (a[i]<0){a[i+1]--;a[i]+=10;}}while(!a[n]&&n>1) n--;sum++;
}
int main()
{cin>>s1>>s2;//n=s1.size();// m=s2.size();n=strlen(s1);m=strlen(s2);for (int i=1;i<=n;i++) a[i]=s1[n-i]-'0';for (int i=1;i<=m;i++) b[i]=s2[m-i]-'0';while (bol()){cut();}cout<<sum<<endl;while (n) cout<<a[n--];return 0;
}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询