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

处理大型数组时reduce()返回NaN?LeetCode 1822问题排查

LeetCode 1822题:reduce计算乘积返回NaN的原因及解决办法

问题场景

你在解决LeetCode 1822题时遇到了问题:题目要求实现一个signFunc,数值为正返回1、负返回-1、零返回0,最终要返回数组所有元素乘积的signFunc结果。

你的初始代码如下:

var arraySign = function(nums) {
  return Math.sign(nums.reduce((acc, curr) => acc * curr));
};

小型数组测试正常,但传入包含超大数值的长数组时,结果却返回NaN。你临时改用条件判断的方式规避了问题:

var arraySign = function(nums) {
  let product = nums.reduce((acc, curr) => acc * curr);
  if(product>0) return 1;
  else if (product<0) return -1;
  else return 0;
};

但你想知道:reduce本身有什么限制吗?为什么会出现这种情况?

问题根源

reduce函数本身没有任何限制,问题出在直接计算超大数组元素乘积时触发了JavaScript的数值溢出:

  • JavaScript使用双精度浮点数存储Number类型,只能安全表示-(2^53 - 1)到2^53 - 1之间的整数。当数组元素数量多、数值大时,乘积会超出这个范围,最终变成Infinity或-Infinity。
  • 如果数组中同时存在0,Infinity * 0或-Infinity * 0的计算结果是NaN,这就导致reduce返回NaN,而Math.sign(NaN)自然也返回NaN。
  • 你的临时方案其实是靠else return 0处理了NaN的情况,但这是逻辑漏洞:NaN不等于乘积为0,只是计算溢出导致的异常值,这种处理可能在某些测试用例下得到错误结果。

正确的解决思路

其实根本不需要计算实际乘积——我们只需要关注两个关键信息就能得到结果:

  1. 数组里有没有0?有就直接返回0;
  2. 数组里负数的个数是奇数还是偶数?偶数返回1,奇数返回-1。

按这个思路写的代码既不会触发溢出,效率还更高(遇到0可以直接终止遍历):

var arraySign = function(nums) {
  let negativeCount = 0;
  for (const num of nums) {
    if (num === 0) return 0;
    if (num < 0) negativeCount++;
  }
  return negativeCount % 2 === 0 ? 1 : -1;
};

内容的提问来源于stack exchange,提问作者Jan Kamoń

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:27:54