前言:

输入输出实现代码
std::ostream& operator<<(std::ostream& os, __int128 n) {
    if (n == 0) return os << '0';
    
    std::string s;
    bool negative = false;
    if (n < 0) {
        negative = true;
        n = -n;
    }
    
    while (n > 0) {
        s += '0' + (n % 10);
        n /= 10;
    }
    
    if (negative) s += '-';
    std::reverse(s.begin(), s.end());
    return os << s;
}
std::istream& operator>>(std::istream& is, __int128& n) {
    std::string s;
    is >> s;
    n = 0;
    bool negative = false;
    size_t start = 0;
    if (s[0] == '-') {
        negative = true;
        start = 1;
    }
    for (size_t i = start; i < s.size(); ++i) {
        n = n * 10 + (s[i] - '0');
    }
    if (negative) n = -n;
    return is;
}

C++ __int128 完全详解

一、基本概念

__int128 是 GCC 和 Clang 编译器提供的非标准扩展类型,用于表示128位整数。

// 基本声明
__int128          a;  // 有符号128位整数
unsigned __int128 b;  // 无符号128位整数

二、数值范围

类型 最小值 最大值 十进制范围
__int128 -2^127 2^127-1 约 -1.7e38 ~ 1.7e38
unsigned __int128 0 2^128-1 0 ~ 约 3.4e38
// 边界值(需要计算)
// 2^127 = 170141183460469231731687303715884105728
// 2^127-1 = 170141183460469231731687303715884105727

三、支持的操作

__int128 a = 10, b = 3;

// ✅ 所有算术运算
__int128 sum = a + b;      // 加法
__int128 diff = a - b;     // 减法
__int128 prod = a * b;     // 乘法
__int128 quot = a / b;     // 除法(向零取整)
__int128 rem = a % b;      // 取模

// ✅ 位运算
__int128 and_op = a & b;   // 按位与
__int128 or_op = a | b;    // 按位或
__int128 xor_op = a ^ b;   // 按位异或
__int128 not_op = ~a;      // 按位取反
__int128 left = a << 2;    // 左移
__int128 right = a >> 2;   // 右移(算术右移)

// ✅ 比较运算
bool eq = (a == b);
bool lt = (a < b);
bool gt = (a > b);
// ... 所有比较运算符都支持

// ✅ 复合赋值
a += b; a -= b; a *= b; a /= b; a %= b;
a &= b; a |= b; a ^= b;
a <<= 2; a >>= 2;

// ✅ 自增自减
a++; ++a; a--; --a;

四、输入输出问题(重点)

标准库完全不支持 __int128 的输入输出,必须手动实现:

输入输出实现

std::ostream& operator<<(std::ostream& os, __int128 n) {
    if (n == 0) return os << '0';
    
    std::string s;
    bool negative = false;
    if (n < 0) {
        negative = true;
        n = -n;
    }
    
    while (n > 0) {
        s += '0' + (n % 10);
        n /= 10;
    }
    
    if (negative) s += '-';
    std::reverse(s.begin(), s.end());
    return os << s;
}
std::istream& operator>>(std::istream& is, __int128& n) {
    std::string s;
    is >> s;
    n = 0;
    bool negative = false;
    size_t start = 0;
    if (s[0] == '-') {
        negative = true;
        start = 1;
    }
    for (size_t i = start; i < s.size(); ++i) {
        n = n * 10 + (s[i] - '0');
    }
    if (negative) n = -n;
    return is;
}

using namespace std;后面加上这行代码,你就能正常cin,cout _int128类型的数了

五、字面量问题

没有直接的128位字面量,需要转换:

// ❌ 错误:直接写大数
__int128 a = 170141183460469231731687303715884105727;  // 编译错误

// ✅ 正确方法1:强制转换
__int128 b = (__int128)1234567890123456789LL * 1000000000;

// ✅ 正确方法2:使用宏
#define INT128_C(x) ((__int128)x)

// ✅ 正确方法3:字符串解析
__int128 c = read_int128();  // 从字符串输入

// ✅ 正确方法4:分段构造
__int128 d = ((__int128)987654321 << 64) | 123456789;

六、常见应用场景

1. 大数乘法防溢出

// 计算 a * b % mod(a, b, mod < 2^64)
uint64_t mul_mod(uint64_t a, uint64_t b, uint64_t mod) {
    __uint128_t result = (__uint128_t)a * b;
    return (uint64_t)(result % mod);
}

// 快速幂取模
uint64_t pow_mod(uint64_t base, uint64_t exp, uint64_t mod) {
    __uint128_t result = 1;
    while (exp > 0) {
        if (exp & 1) result = (result * base) % mod;
        base = (__uint128_t)base * base % mod;
        exp >>= 1;
    }
    return (uint64_t)result;
}

2. 精确计算大数

// 计算组合数 C(n, m) 避免溢出
__int128 combination(int n, int m) {
    if (m < 0 || m > n) return 0;
    if (m > n - m) m = n - m;
    
    __int128 result = 1;
    for (int i = 1; i <= m; ++i) {
        result = result * (n - m + i) / i;
    }
    return result;
}

3. 高精度计时/计数器

// 纳秒级计数器
unsigned __int128 get_cycles() {
    unsigned __int128 cycles;
    // 使用 RDTSC 指令(x86)
    uint64_t high, low;
    asm volatile("rdtsc" : "=a"(low), "=d"(high));
    cycles = ((unsigned __int128)high << 64) | low;
    return cycles;
}

4. 密码学应用

// 模拟128位寄存器
__uint128_t rotate_left(__uint128_t value, int shift) {
    shift &= 127;
    return (value << shift) | (value >> (128 - shift));
}

// AES MixColumns 等操作

注意事项

  1. 不是标准C++,依赖编译器扩展
  2. 内存占用:16字节(对齐可能更大)
  3. 调试困难:调试器可能无法直接显示值
  4. 序列化问题:不能直接写入文件或网络传输
  5. long long混用:注意类型提升规则

总结

  • 适合:需要128位精度的性能敏感场景
  • 不适合:需要跨MSVC平台、任意精度、简单IO的场合
  • 💡 建议:封装成类来处理IO,或考虑Boost作为替代