You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ long类型乘法溢出场景下ULL后缀的正确使用方法

问题根因

该报错本质是有符号整数运算溢出:

  • 代码中b、c均为long类型,在大部分32位编译环境、甚至部分64位Windows编译环境中,long为32位有符号整数,最大可表示值仅为2^31-1(约21亿)
  • 运算b*c时,两个操作数都是long类型,会先以long类型执行乘法:输入为1000000000、1000000000、1时,b和c都是1000000000,乘积为1e18,远超过32位long的上限,运算阶段就已经触发溢出,后续赋值给unsigned long long类型的d也无法挽回溢出问题。
ULL的正确使用方法

ULL是C++中unsigned long long类型的字面量后缀,仅作用于数字字面量,作用是声明该字面量为64位无符号整数类型。当表达式中存在unsigned long long类型的操作数时,其他参与运算的整数类型会自动提升为unsigned long long,整个运算过程都在64位无符号整数的范围内执行,即可避免该场景下的溢出。

针对该代码的两种正确修正方案

方案1:在乘法运算开头加入1ULL,强制提升整个运算的类型

只需修改乘法一行即可,注意1ULL要放在运算的最左侧,保证第一个运算就触发类型提升:

d = 1ULL * b * c;

错误写法示例:d = b * c * 1ULL; 这种写法会先执行b*c的long类型运算,已经溢出后再和1ULL计算,无法解决问题。

方案2:直接将b、c声明为unsigned long long类型

从根源上保证运算的变量类型就是64位无符号整数:

#include <iostream>
using namespace std;
int main()
{
    long n,m,a;
    cin >> n >> m >> a ;
    // 把b、c改成unsigned long long类型
    unsigned long long b,c;
    b = (n%a==0)?(n/a):((n/a)+1);
    c = (m%a==0)?(m/a):((m/a)+1);

    unsigned long long d = b*c;
    cout<<d;
}
常见使用注意事项
  • ULL只能加在数字字面量后面,不能加在变量名后面,比如bULL是非法写法
  • 涉及大数运算时,要保证类型提升发生在运算之前,不要等溢出后再做类型转换
  • 如果运算结果超过unsigned long long的上限(2^64-1,约1.8e19),还是会出现截断,需要根据题目范围选择更大的整数类型或者高精度实现。

内容的提问来源于stack exchange,提问作者Anmol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 22:24:04