高精
这几天做题遇到一些关于高精的题,很烦的!
一开始是用双long long 强行拼凑的int128,但是有点局限,今天搜集资料自己写了下高精
个人感觉(我的高精)良好(我是对付用了),就写进博文里,欢迎大家看看,提提意见。
结构体
1 int len,s[50];//习惯性扔掉位置零ps:位置零其实可以存长度的 2 int128() { memset(s, 0, sizeof(s)); len = 0; }
主要就是数组存储每位的数字,加上长度变量便于计算(没感觉到~//结构体借鉴来的hhh~)(自己需要的构造函数自己加上)
然后就是一些基本功能的重载
1 bool operator == (const int128& a, const int128& b) { 2 if (a.len != b.len)return 0; 3 for (int i = max(a.len, b.len); i >= 0; --i) 4 if (a.s[i] != b.s[i])return 0; 5 return 1; 6 } 7 bool operator > (const int128& a, const int128& b) { 8 if (a.len < b.len)return 0; 9 for (int i = max(a.len, b.len); i >= 0; --i) 10 if (a.s[i] > b.s[i])return 1; 11 else if (a.s[i] < b.s[i])break; 12 return 0; 13 } 14 bool operator < (const int128& a, const int128& b) { 15 if (a.len > b.len)return 0; 16 for (int i = max(a.len, b.len); i >= 0; --i) 17 if (a.s[i] < b.s[i])return 1; 18 else if (a.s[i] > b.s[i])break; 19 return 0; 20 } 21 bool operator >= (const int128& a, const int128& b) { 22 if (a.len < b.len)return 0; 23 for (int i = max(a.len, b.len); i >= 0; --i) 24 if (a.s[i] < b.s[i])return 0; 25 else if (a.s[i] > b.s[i])break; 26 return 1; 27 } 28 bool operator <= (const int128& a, const int128& b) { 29 if (a.len > b.len)return 0; 30 for (int i = max(a.len, b.len); i >= 0; --i) 31 if (a.s[i] > b.s[i])return 0; 32 else if (a.s[i] < b.s[i])break; 33 return 1; 34 }
然后开始实现基本功能
1.加
int128 operator + (int128 a, int128 b) { int128 temp; temp.len = max(a.len, b.len); for (int i = 1; i <= temp.len; ++i) { temp.s[i] += (a.s[i] + b.s[i]); if (temp.s[i] >= 10) { temp.s[i] -= 10; temp.s[i + 1] += 1; }//毕竟十进制数单位相加,总不能加出20吧,hhh~ } if (temp.s[temp.len + 1])++temp.len; return temp; }
直接逐位相加进位就行
2.减
int128 operator - (int128 a, int128 b) {//对于减法,我的思路比较麻烦,就是类似二进制相减//由于懒着写符号我这里无论a>b还是b>a统统大减小 int128 temp; temp.len = max(a.len, b.len); b.len = a.len = temp.len; if (a < b)//如果a较小,则对a取反 for (int i = 1; i <= temp.len; ++i) a.s[i] = 9 - a.s[i]; else//否则对b取反 for (int i = 1; i <= temp.len; ++i) b.s[i] = 9 - b.s[i]; temp = a + b + 1;//不要忘记加一??? temp.len = a.len; for (int i = temp.len; i >= 1; --i)//把零位删除 if (!temp.s[i])temp.len--; else break;//遇到第一个非零位即退出 temp.s[temp.len + 1] = 0; return temp; }
这里我直接让小的数字取反(十进制取反???(我想出来的???))(就是逐位被9减而已),然后两个数字相加,在加一就可以了(毕竟没有补码~)
3.乘
int128 operator * (int128 a, int128 b) { int128 temp; if (a == zero || b == zero)return zero;//任意一方为零则返回零 temp.len = a.len + b.len - 1;//最小位数 for (int i = 1; i <= a.len; ++i) for (int j = 1; j <= b.len; ++j) { temp.s[i + j - 1] += a.s[i] * b.s[j];//各个位置相乘进行存储 } for (int i = 1; i <= temp.len; ++i) { temp.s[i + 1] += temp.s[i] / 10;//大于个位的部分要前进 temp.s[i] %= 10; } if (temp.s[temp.len + 1])++temp.len;//最高位十进制数相乘,总不能乘出三位数吧,hhh~ return temp; }
这个直接模仿正常相乘做的,(借鉴的思路QAQ)个人感觉好妙啊~
4.除
int128 operator / (int128 a, int128 b) { int128 temp; while (a > b) { a = a - b; temp = temp + 1; } return temp; }
直接减就可以了
5.输出输入
ostream& operator << (ostream& out, int128 a) { for (int i = a.len; i > 0; --i) out << a.s[i]; return out; } istream& operator >> (istream& in, int128& a) { memset(a.s, 0, sizeof(a.s)); a.len = 0; char c[50]; in >> c; while (c[a.len++] != '\0'); a.len--; for (int i = 1; i <= a.len; ++i) { a.s[i] = c[a.len - i] - '0'; } return in; }
大功告成!
有错误请留言,感谢大家能看到这篇文章

浙公网安备 33010602011771号