老纸不想写高精度
故学了下__int128
**_int128 (有符号)_**
- 类型:128位有符号整数
- 最大能存:约
170,141,183,460,469,231,731,687,303,715,884,105,727(约 1.7 × 10³⁸) - 十进制大约能存 39 位数。
**不过,用的时候有两点要特别注意:**
- 它不是标准C++ :
__int128是 GCC 和 Clang 编译器的扩展,Visual Studio 的 MSVC 编译器不支持。在竞赛或Linux环境下通常没问题。 - 输入输出麻烦 :你不能直接用
cin、cout、scanf或printf来读写__int128,需要自己写专门的快读快写函数。
输入输出
方法一:手写快读快写函数(最常用)
这是竞赛中最常见的方式,直接调用 read() 和 write() 函数:
cpp
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
// 快读
__int128 read() {
__int128 x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
// 快写
void write(__int128 x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
int main() {
__int128 a = read();
__int128 b = read();
write(a + b);
return 0;
}
方法二:重载 >> 和 << 运算符
重载之后就可以像普通类型一样直接用 cin/cout 了,写起来更顺手:
cpp
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
// 重载输入
istream& operator>>(istream& is, __int128& n) {
string s;
is >> s;
n = 0;
bool neg = false;
int i = 0;
if (s == '-') {
neg = true;
i = 1;
}
for (; i < s.size(); i++) {
n = n * 10 + (s[i] - '0');
}
if (neg) n = -n;
return is;
}
// 重载输出
ostream& operator<<(ostream& os, __int128 n) {
if (n == 0) return os << "0";
if (n < 0) {
os << '-';
n = -n;
}
string s;
while (n) {
s.push_back('0' + n % 10);
n /= 10;
}
reverse(s.begin(), s.end());
return os << s;
}
int main() {
__int128 a, b;
cin >> a >> b;
cout << a + b << endl;
return 0;
}
需要注意的点
- 编译器限制 :
__int128是 GCC 和 Clang 的扩展,MSVC(Visual Studio)不支持,在 Linux 或竞赛环境(如洛谷、Codeforces)中通常没问题。 - 性能 :重载运算符内部用字符串转换,效率比快读快写稍低,但一般够用。如果数据量极大(比如百万级),建议用
getchar/putchar版本的快读快写。 - 负数处理:写函数时别忘了处理负号,否则输出会出错。
还不如写高精度呢,超