JavaScript回文数判断时大数字输出结果异常问题排查
JavaScript回文数校验函数大数值判断异常排查
问题现象
现有回文数校验逻辑通过「反转数值后和原数比较」的思路实现,测试时出现结果不一致问题:
- 传入参数
23456788888765432时,判断结果正确 - 传入参数
234567888888765432时,无法返回正确的回文判断结果
原实现代码如下:
function allPalindromicPerms(num) { // find reverse of a number and then // comapre the reversed number with the main number var finalNum = 0; var originalNum = num; let remainder = 0; while (num) { remainder = num % 10; console.log('remainder' + remainder); num = num - remainder; num = num / 10; finalNum = finalNum * 10 + remainder; console.log(finalNum); } if (finalNum == originalNum) { console.log("is palindrome"); } else { console.log("not a palindrome"); } } allPalindromicPerms(23456788888765432) // 输出正常 allPalindromicPerms(234567888888765432) // 输出错误
根因分析
异常的核心原因是JavaScript Number类型的安全整数范围限制:
- JS中常规数字类型是64位双精度浮点数,能精确表示的最大安全整数为
Number.MAX_SAFE_INTEGER,值为9007199254740991(即2^53-1) - 测试异常的参数
234567888888765432远大于安全整数上限,数值传入时就已经出现精度丢失,后续取余、除法、拼接反转数的所有运算结果都会和真实值存在偏差,最终导致判断错误 - 原代码本身还存在小隐患:
num = num / 10使用普通除法,运算后可能得到浮点数,即使在安全整数范围内也存在隐式转换风险,应该替换为整数除法逻辑。
修复方案
针对大数值回文判断场景,最稳妥的实现是放弃数值运算思路,转为字符串比对,从根源规避精度问题:
function allPalindromicPerms(num) { // 数字转字符串,避免大整数精度丢失 const numStr = String(num); let start = 0; let end = numStr.length - 1; // 双指针从首尾向中间逐位比对 while (start < end) { if (numStr[start] !== numStr[end]) { console.log("not a palindrome"); return; } start++; end--; } console.log("is palindrome"); }
如果运行环境支持ES2020+标准,也可以使用BigInt类型处理大整数运算,注意运算过程中要使用整数除法取整,避免出现小数。
内容的提问来源于stack exchange,提问作者Ankita Sarda
相关产品推荐
相关产品推荐

