JavaScript下超maxint大数的可靠乘法与模运算实现问询
解决JavaScript大整数模运算溢出问题
嘿,我完全明白问题出在哪了——JavaScript的Number类型处理不了大于2^53 - 1(也就是9007199254740991)的整数,所以你的超大数值计算被截断了,结果自然错了。解决办法是利用模运算的数学性质,把复杂的大计算拆分成一个个小的、安全的步骤,不用直接处理那些天文数字。
核心数学原理
模运算有几个关键性质(我们把最终要取的模数记为m):
(a * b) % m = [(a % m) * (b % m)] % m:乘法的模可以拆成每个因子先取模,相乘后再取模,结果不变- 连续整数
n和n-1相乘的结果必为偶数,所以n*(n-1)/2肯定是整数,我们可以先拆分除法操作,避免处理超大数的除法
分步计算方案
你的目标计算公式本质是:
result = [( (n*(n-1)/2 )² ) * r ] % m
(其中n是numberOfColumns,r是numberOfRows,m是valueOverflow)
我们一步步拆解:
计算
totalOfSingleRow的模值:
因为n=34359738368是偶数,我们先把它除以2,再和n-1相乘,每一步都取模m:const m = 13719506; const n = 34359738368; const r = 28827050410; const halfNMod = (n / 2) % m; const nMinus1Mod = (n - 1) % m; // 得到 totalOfSingleRow % m const A = (halfNMod * nMinus1Mod) % m;如果
n是奇数,就改成计算n % m和(n-1)/2 % m,逻辑完全一致。计算
A的平方模m:const B = (A * A) % m;结合行数的模值得到最终结果:
const rMod = r % m; const result = (B * rMod) % m;
验证结果
按照这个逻辑计算,最终会得到预期的10552574,而不是错误的8479672。全程处理的数值都远小于m(13719506),完全在JavaScript的安全整数范围内,不会有精度丢失。
完整可运行代码
function getCorrectResult() { const numberOfColumns = 34359738368; const numberOfRows = 28827050410; const valueOverflow = 13719506; const m = valueOverflow; // 处理totalOfSingleRow的模,兼容奇偶列数 let halfTerm, pairedTerm; if (numberOfColumns % 2 === 0) { halfTerm = numberOfColumns / 2; pairedTerm = numberOfColumns - 1; } else { halfTerm = (numberOfColumns - 1) / 2; pairedTerm = numberOfColumns; } const halfTermMod = halfTerm % m; const pairedTermMod = pairedTerm % m; const singleRowMod = (halfTermMod * pairedTermMod) % m; // 计算平方模 const squaredSingleRowMod = (singleRowMod * singleRowMod) % m; // 结合行数模得到最终结果 const rowMod = numberOfRows % m; const result = (squaredSingleRowMod * rowMod) % m; return result; // 返回10552574 }
这个方案效率极高,不需要字符串操作或者外部库,完全符合Codewars的提交要求。
内容的提问来源于stack exchange,提问作者Rick Hoving
相关产品推荐
相关产品推荐

