当前位置: 首页 > news >正文

【杂谈】------使用 __int128 处理超大整数计算

一、整数类型的表示范围

常见整数类型在 C++ 中的表示范围如下(带符号):
当然可以,下面是在你的基础上添加了“字节”这一列的完整表格:

类型位数字节数表示范围(最大值约等于)
int324231 − 1 ≈ 2.1×10⁹
long long648263 − 1 ≈ 9.2×10¹⁸
__int128128162127 − 1 ≈ 1.7×10³⁸

二、数值膨胀的来源

假设你要处理如下乘积(三角形代价计算):

w[i] * w[k] * w[j]

而每个权值最大为 10^9,则:

最大乘积 = 10^9 × 10^9 × 10^9 = 10^27

三、long long 无法表示 10^27

long long 的最大值是:

2^63 − 1 ≈ 9.2 × 10^18

10^27 是其 约 10^8 倍,远远超出范围。

如果继续用 long long,即使只计算一次这样的乘法,也必定溢出。


四、使用 __int128 是最佳解决方案

__int128 的最大值约为:

2^127 ≈ 1.7 × 10^38

而你只需表示 10^27绰绰有余,因此推荐使用 __int128


五、__int128 的使用方法

1. 定义变量

__int128 a = 1234567890123456789;
__int128 b = a * a;

使用别名方便阅读:

using lll = __int128;
lll x = 1;

2. 四则运算

和普通整数一样操作:

__int128 a = 1e12;
__int128 b = a * a;  // 1e24
__int128 c = b / 1000000;

3. 输出函数(重点)

由于 cout 不支持 __int128,需手动转换为字符串输出:

// 函数:print128
// 功能:输出 __int128 类型的整数(128位整数)
// 参数:x - 要输出的 __int128 类型的数
void print128(__int128 x) 
{// 特判:如果是 0,直接输出并返回if (x == 0) {cout << "0";return;}// 如果是负数,先输出负号,然后取相反数变成正数if (x < 0) {cout << "-";x = -x;}string s;  // 用于存储每一位数字(逆序)// 将整数转为字符串(注意是从低位往高位推)while (x > 0) {s += (x % 10) + '0';  // 取最低位,并转成字符存入字符串x /= 10;              // 去掉最低位}// 当前字符串是反着的,需要反转成正常顺序reverse(s.begin(), s.end());// 输出最终的字符串cout << s;
}

4. 输入函数(重点)

// 函数:read128
// 功能:从标准输入读取一个整数(可以是负数),并将其转换为 __int128 类型返回
__int128 read128() 
{string s;cin >> s;  // 从标准输入读取一个字符串,代表一个整数(可能为负数)bool neg = false;  // 用于标记输入的数字是否为负数int i = 0;         // 遍历字符串的起始位置// 如果字符串的首字符是负号,则标记为负数if (s[0] == '-') {neg = true;  // 记录负号标志i = 1;       // 从下标 1 开始处理数字部分}__int128 res = 0;  // 初始化结果为 0,用于保存转换后的整数值// 遍历字符串的每一位数字字符for (; i < s.size(); i++) {// 将字符转换为对应数字('0' → 0, '1' → 1, ..., '9' → 9)// 并将其累加到结果中(相当于 res = res * 10 + 当前数字)res = res * 10 + (s[i] - '0');}// 如果是负数,则结果取相反数return neg ? -res : res;
}

5. 示例程序:三数乘积

#include <bits/stdc++.h>
using namespace std;//输出函数板子:
void print128(__int128 x) 
{if (x == 0) {cout << "0";return;}if (x < 0) {cout << "-";x = -x;}string s;while (x > 0) {s += (x % 10) + '0';x /= 10;              }reverse(s.begin(), s.end());cout << s;
}int main() 
{long long a, b, c;cin >> a >> b >> c;//注意隐式类型提升 与 强制类型转换的结合 问题__int128 res = (__int128)a * b * c;print128(res);cout << "\n";return 0;
}

6.隐式类型提升 与 强制类型转换

  • 类型提升(Promotion):当一个表达式中涉及多个不同整数类型(如 int、long、long long、__int128)时,C++ 会自动将较小的类型提升到更大的类型,以保证运算的精度和正确性。
  • 强制类型转换:如__int128 res = (__int128)a * b * c;

即:只要表达式中有一个是 __int128,那么整个表达式就会被提升为 __int128 运算。

7. 编译方式

只要你使用 GCC 或 Clang,直接编译即可:

g++ -std=c++17 -O2 yourcode.cpp -o yourcode

⚠️ 注意:__int128Windows 的 MSVC 编译器 中不支持,仅适用于 Linux/macOS 下的 GCC 或 Clang。


六、总结

操作支持情况
定义变量✅ 支持
四则运算✅ 支持
比较操作✅ 支持
cin/cout 支持❌ 不支持,需要自写
GCC/Clang 支持✅ 支持
MSVC 支持❌ 不支持

七、替代方案(仅当不能用 __int128 时)

  1. 手写大整数类(如字符串模拟乘法)
  2. 使用 GMP 等大整数库(重量级方案)

相关文章:

  • MyBatis深度解析:XML/注解配置与动态SQL编写实战
  • TinyVue v3.23.0 正式发布:增加 NumberAnimation 数字动画组件、支持全局配置组件的 props
  • FreeRTOS 在物联网传感器节点的应用:低功耗实时数据采集与传输方案
  • 资源回收:为地球减负,共创绿色未来
  • 超临界机组协调控制系统建模项目开发笔记
  • ubuntu 22.04 配置静态IP、网关、DNS
  • MySQL进阶实战:窗口函数 VS 聚合函数,性能与场景全对比
  • MyBatis 与 Spring 框架集成详解:构建企业级数据访问层
  • 泛型(1)
  • Elasticsearch实战:法律文档索引与管理的技术实践
  • Baklib的智能推荐系统核心是什么?
  • 【大模型】分词(Tokenization)
  • 【AI论文】LLaDA-V:具备视觉指令微调能力的大型语言扩散模型
  • Python基础教程:从零开始学习编程 - 第1-3天
  • 中国工程咨询协会新型基础设施专业委员会成立
  • C++:多重继承
  • 一些git的常见操作记录
  • 2556. 第八大奇迹
  • 机器学习-朴素贝叶斯分类
  • IP协议解析
  • 天津市工程建设公众信息网官网/武汉seo网站推广培训
  • app网站及其特色/软文推广代理平台
  • 互联网网站建设哪里好/天津网站排名提升多少钱
  • 黔西南北京网站建设/百度秒收录软件工具
  • 佛山专业的网站建设公司/百度网络营销中心app
  • 做ppt的素材免费网站/关键词是指什么