--- title: "_int128" created: 2025-11-28 tags: - 算法 --- # _int128 ## 前言 高精度问题很大程度上可以用这个\_int128解决 无需去写一大串的vector模拟(加减乘除全得写 半个多小时就过去了……) 在noi是可以用的 然后蓝桥杯方面 还在问组委会 应该是可以的 官方提供的dev是可以写的 int: 2147483648, 即 $2^{31}≈ 2×10^{10}$ long long :9223372036854775807 , 即 $2^{63}≈9×10^{19}$ \_int128的最大值是:85070591730234615865843651857942052864 , 约为 $10^{38}$ 换算成位的话 大概就是能表示**38位的10进制数字** 在大部分时候是可以解决高精度问题的 除非说什么涉及到 $10^{几百位}$ 这样的数 (几道例题就不行 那是刁钻的考高精度 平时只是数据范围过大恶心一下人的话 用\_int128会方便很多) ## 正式点的概念 `__int128` 是 GCC 编译器提供的一种扩展类型,用于表示 128 位的整数。 在 C++ 中,标准类型最大只支持到 64 位的整数(例如 `long long`),但有些应用场景下需要更大范围的整数,这时就可以使用 `__int128` 类型。 使用 `__int128` 需要注意以下几点: 1. `__int128` 不是 C++ 标准的一部分,这意味着它不是所有编译器都支持的。通常只有 GCC 和支持 GCC 扩展的编译器(如 Clang)支持 `__int128`。 2. 因为 `__int128` 不是标准类型,标准的输入输出流(如 `std::cin` 和 `std::cout`)并不直接支持它,所以你需要使用其他方式来输入和输出 `__int128` 类型的变量,或者转换为可以输出的类型,例如通过分解数字或者转换为字符串。 3. 对于 `__int128` 的运算,编译器可能会生成更多的指令来处理这些操作,因此运算可能会比 64 位整数慢。 ## 使用 **1、声明** `__int128` **类型的变量**:由于 `__int128` 是 GCC 编译器的扩展类型,你可以直接声明 `__int128` 类型的变量。 ``` __int128 variable_name; ``` **2、输入** `__int128` **类型的值**:标准输入流(`std::cin`)不支持直接读取 `__int128` 类型的值,因此需要手写一个读取函数`read()` **读取 (**`read` **函数):** 1. 初始化变量 `x` 为0,它将存储最终的数值。初始化 `f` 为1,它是一个标志变量,用来表示数值的正负。 2. 使用 `getchar()` 函数逐字符读取输入。 3. 使用一个 `while` 循环跳过所有非数字字符。如果读取到减号(`'-'`),将 `f` 设置为-1,表示这是一个负数。 4. 继续使用 `while` 循环,当读取到数字字符时,将其转换为数字并累加到 `x` 上。这里的转换通过减去字符 `'0'` 的 ASCII 值来实现。 5. 每读取一个数字字符,都将 `x` 乘以10(向左移动一个十进制位),然后加上新读取的数字。 6. 读取完所有数字后,根据 `f` 的值调整 `x` 的符号,并返回结果。 ```cpp __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; } ``` **3、输出** `__int128` **类型的值**:同样,标准输出流(`std::cout`)不支持直接打印 `__int128` 类型的值,需要手写输出函数,比如上面的 `write()` 函数。 **写入 (**`write` **函数):** 1. 检查 `x` 是否为负数。如果是,输出一个减号,并将 `x` 取相反数,以便后面的步骤只处理正数。 2. 如果 `x` 大于9(也就是说 `x` 至少有两位数),则递归调用 `write` 函数,先输出 `x / 10` 的结果(也就是除去最后一位的所有其他位)。 3. 最后,输出 `x % 10` 的结果(`x` 的最后一位),使用 `putchar` 函数,并且通过 `+ '0'` 转换数字到对应的字符。 4. 递归调用 `write` 直到 `x` 变成个位数,然后依次由高到低输出每一位。 ```cpp void write(__int128 x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x / 10); putchar(x % 10 + '0'); } ``` **4、进行算术运算**:`__int128` 支持标准的算术运算符,比如 `+`, `-`, `*`, `/`。 ``` __int128 a = read(); __int128 b = read(); __int128 c = a * b; // +-*/ write(c); ``` **5、处理** `__int128` **的限制**:如上所述,`__int128` 不是 C++ 标准的一部分,所以标准库的功能(如输入输出、转换为字符串等)不可用。需要手动实现这些功能。 ## 模板 ```cpp #include using namespace std; typedef __int128 LL; LL read() { LL 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(LL x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x / 10); putchar(x % 10 + '0'); } int main() { LL a = read(); LL b = read(); LL sum = a + b; LL del = a - b; LL mul = a * b; LL div = a / b; LL mod = a % b; cout<<"sum: "; write(sum); cout<