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

C语言int变量三次连乘赋值给long为何发生整数溢出?

核心结论

你的判断完全准确:C语言中算术表达式的求值类型由参与运算的操作数类型决定,和最终赋值的目标类型没有关系。赋值触发的类型转换,只会在右侧整个表达式全部计算完成后才执行,不会提前改变运算过程中的中间值类型。

溢出原因拆解

你给出的问题代码如下:

void main(void) {
    int n = 1291;
    long cube = n*n*n;
    printf("Cube: %ld, n: %d", cube, n);
}

n*n*n是左结合的算术运算,会按照以下顺序分步求值,全程在int类型下计算:

  • 第一步计算n * n:两个操作数均为int,结果类型为int。1291的平方是1666681,处于32位int的取值范围(-2147483648 ~ 2147483647)内,这一步无异常。
  • 第二步计算上一步结果 * n:两边操作数依然是int,结果类型仍为int。此时乘积为2151685171,超过32位int的最大值2147483647,触发有符号整数溢出,得到补码截断后的错误值-2143282125。
  • 等整个连乘运算完成、溢出的错误结果已经生成后,才会执行赋值阶段的类型转换,把这个错误的int值转为long存入cube变量,此时已经无法得到正确结果。

这也是你把n的类型改为long后运行正常的原因:当n本身是long类型时,每一步乘法的操作数都是long,中间结果也会按long类型存储,全程不会触发int范围的溢出,自然能得到正确的计算值。

修复方法

不需要把n整体声明为long,只要在链式运算的第一步将任意一个操作数强转为long,就能让后续所有运算自动提升到long精度,避免溢出:

void main(void) {
    int n = 1291;
    long cube = (long)n * n * n;
    printf("Cube: %ld, n: %d", cube, n);
}

运行后可得到预期输出:

Cube: 2151685171, n: 1291

注意:不要把强转写为(long)(n*n*n),这种写法是先完成int类型的连乘、已经触发溢出后再做类型转换,和原错误写法没有区别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:36:17