非负数高精度
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAX_LEN = 1001, CARRY = 4, BASE = 10000; struct BigInt { private: int A[MAX_LEN]; int Len; public: void Clear() { memset(A, 0, sizeof(A)); Len = 0; } void Set(int x) { Clear(); while (x) { A[Len++] = x%BASE; x /= BASE; } while (Len > 0 && !A[Len]) Len--;//规定动作不要改 } BigInt() { Clear(); } BigInt(int x) { Set(x); } void Read(char *s) { Clear(); int cur = 0, pos = 0, pow = 1; for (int i = strlen(s) - 1; i >= 0; i--)//易忘点:倒序循环。因为位数小的数字在右边。//易忘点:-1 { cur += (s[i] - '0')*pow; pow *= 10;//易忘点 if (++pos == CARRY) { A[Len++] = cur; cur = pos = 0; pow = 1; } } if (!pos)//最好按照pos来判断。 Len--; else A[Len] = cur; } void Read() { char s[MAX_LEN*CARRY]; scanf("%s", s); Read(s); } void Print() { printf("%d", A[Len]);//易忘点。否则输出的数字前面多了几个0. for (int i = Len - 1; i >= 0; i--) printf("%0*d", CARRY, A[i]);//易忘点:%0*d。否则每一位前面的几个0没有输出。 printf("\n"); } BigInt operator = (const BigInt &a) { memcpy(A, a.A, sizeof(A)); Len = a.Len; return *this; } bool operator < (const BigInt &a) { if (Len != a.Len) return Len < a.Len; for (int i = Len; i >= 0; i--) if (A[i] != a.A[i]) return A[i] < a.A[i]; return false; } BigInt operator += (const BigInt &a) { Len = max(Len, a.Len); for (int i = 0; i <= max(Len, a.Len); i++) { A[i] = (A[i] + a.A[i]); A[i + 1] += A[i] / BASE;//易忘点:不是(A[i]+a.A[i])/BASE,因为A[i]是修改后的值 A[i] %= BASE;//易忘点:不要与第一句写在一起。//易忘点:此句和上一句/和%不要写反了 } if (A[Len + 1]) Len++; return *this; } BigInt operator + (const BigInt &a) { BigInt ans = *this; return ans += a; } BigInt operator -= (const BigInt &a) { for (int i = 0; i <= Len; i++) { A[i] -= a.A[i]; if (A[i] < 0) { A[i] += BASE; A[i + 1]--;//易忘点:借位是-,不是+ } } while (Len > 0 && !A[Len])//易忘点:Len>0 Len--; return *this; } BigInt operator - (const BigInt &a) { BigInt ans = *this; return ans -= a; } BigInt operator *= (const BigInt &a) { BigInt b = *this; Clear(); Len = a.Len + b.Len;//以上3句 易忘点:乘法不是在原有乘数的基础上修改出来的,而是一个全新的数字 for (int i = 0; i <= a.Len; i++) { for (int j = 0; j <= b.Len; j++) { A[i + j] += a.A[i] * b.A[j];//易忘点:a. , b.//易忘点:+=,而不是=。相乘的结果最后是要累加的。 A[i + j + 1] += A[i + j] / BASE;//易忘点:A[i+j],而不是a.A[i]*b.A[j] A[i + j] %= BASE;//易忘点:此句不可以与第一句结合在一起,因为第二句要用。 } } if (A[Len + 1]) Len++; return *this; } BigInt operator * (const BigInt &a) { BigInt ans = *this; return ans *= a; } BigInt operator /= (const int x) { for (int i = Len; i >= 0; i--) { if (i > 0) A[i - 1] += A[i] % x * BASE; A[i] /= x;//易忘点:此句并非在if的上面,否则if中的A[i]就是修改后的值了 } while (Len > 0 && !A[Len]) //while(A[0]>0&&A[Len]<=0) Len--; return *this; } BigInt operator / (const int x) { BigInt ans = *this; return ans /= x; } BigInt operator /= (const BigInt &a) { BigInt l, r = *this, one(1);//易忘点:r!=Len, l!=1(*this可能表示0)//易忘点:不能写one=1,因为声明时的=与重定义的=不是一个= while (l < r) { BigInt mid = (l + r + one) / 2; if (*this < (mid * a))//易忘点:<两边不要写反了,此判断说明当前的a选大了。 r = mid - one; else l = mid; } return *this = l; } BigInt operator / (const BigInt &a) { BigInt ans = *this; return ans /= a; } bool IsZero() { return Len == 0 && A[0] == 0; } };