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

为何对1'000'000'007取模后仍出现int溢出?

为什么取模后仍然出现整数溢出?

嘿,这个问题我刷LeetCode的时候也踩过一模一样的坑!咱们来一步步拆解清楚原因:

问题根源:32位int的范围限制

你用的int类型在绝大多数系统里是32位的,它的最大值是2^31 - 1 = 2147483647。虽然你给每个单独的dp值都做了% MOD(MOD=1e9+7),保证了单个值不会超过1e9+6,但多个这样的值相加时,总和很容易突破int的上限。

比如错误日志里的1543295930 + 918080153 = 2461376083,这个数已经比2147483647大了,直接用int相加就会触发有符号整数溢出,属于C++里的未定义行为。

看你代码里出问题的这行:

dp2[1][0] = (dp2[1][0]+dp[1][0]+dp[1][1]+dp[1][2])%MOD;

这里dp2[1][0]已经是一个接近1e9的数,再加上另外三个接近1e9的数,总和最多能达到4*(1e9+6) = 4000000024,这远远超过了32位int的最大值,溢出是必然的。

解决办法:用64位整数做中间计算

把你的dp和dp2数组的类型从int改成long long,这样中间相加的时候就能用64位整数存储总和,避免溢出。64位long long的最大值是9e18,完全能容纳几个1e9级别的数相加。

修改后的代码示例:

class Solution {
public:
    static constexpr int MOD = 1'000'000'007;
    int checkRecord(int n) {
        long long dp[2][3]; // 改为long long类型
        long long dp2[2][3]; // 改为long long类型
        memset(dp, 0, sizeof(dp));
        memset(dp2,0,sizeof(dp2));
        dp[0][0] = 1;
        for(int i=1;i<n+1;i++){
            dp2[0][1] = dp[0][0]%MOD;
            dp2[1][1] = dp[1][0]%MOD;
            dp2[0][2] = dp[0][1]%MOD;
            dp2[1][2] = dp[1][1]%MOD;
            dp2[1][0] = (dp[0][0]+dp[0][1]+dp[0][2])%MOD;
            // 现在用long long相加,不会触发溢出
            dp2[1][0] = (dp2[1][0]+dp[1][0]+dp[1][1]+dp[1][2])%MOD;
            dp2[0][0] = (dp[0][0]+dp[0][1]+dp[0][2])%MOD;
            memcpy(dp, dp2, sizeof(dp));
        }
        int sum = 0;
        for (int j = 0; j <= 1; j++) {
            for (int k = 0; k <= 2; k++) {
                sum = (sum + dp[j][k]) % MOD;
            }
        }
        return sum;
    }
};

这样修改后,所有中间相加的操作都在long long的安全范围内进行,取模后再存储,就不会出现溢出问题了。

内容的提问来源于stack exchange,提问作者周宁音

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 02:58:15