为什么我的数组的最后一个元素被替换成了0?

3

我有一个函数:

function splitToDigits(n) {
    var digits = ("" + n).split("").map(function(item) {
        return parseInt(item, 10);
    });
    console.log(digits);
}

console.log(splitToDigits(123456784987654321));

这里返回 digits = [1,2,3,4,5,6,7,8,4,9,8,7,6,5,4,3,2,0] 的值。
有想法为什么最后一个元素是 0 吗?我注意到当我删除数组中的两个元素时,它就正常了。感谢所有出色的答案! :)

6
由于在数字中存在精度限制,你的号码末尾的1已被替换掉。请尝试运行console.log(123456784987654321)以查看此问题。 - Jaromanda X
你可以使用 Number.isSafeInteger 进行检查:Number.isSafeInteger(123456784987654321) 返回 false,因此你不能必然地将其与其他整数区分开来。 - Ry-
1
请注意,您可以使用 (''+n).split('').map(Number) 来节省一些打字时间。;-) - RobG
2个回答

1
如上方评论区Jaromanda X所述,JavaScript没有足够的精度来跟踪您传递给函数的整数中的每个数字。
为了解决这个问题,您应该传递一个字符串:
console.log(splitToDigits('123456784987654321'))

然而,我还想指出您可以大大简化您的splitToDigits方法:

function splitToDigits(n) {
  return [].map.call(n + '', Number)
}

console.log(splitToDigits('123456784987654321'))
console.log(splitToDigits(1234))


好的,但是如果我稍后以不同的顺序将同一个数字传递给parseInt(),它会执行相同的操作吗? - Griffin Obeid
1
如果您尝试在JavaScript中调用parseInt函数来处理一个过大无法存储的整数,那么您将不可避免地会失去一些精度。您可以使用字符串代替,或者使用上述方法保留数字列表。 - gyre

1
因为JavaScript会截断数字。
最好的方法是通过以下console.log查看:
function splitToDigits(n) {
console.log(n);
var digits = ("" + n).split("").map(function(item) {
    return parseInt(item, 10);
});
}

当你运行splitToDigits(123456784987654321)时,你得到的结果已经是123456784987654320。因此,这与你的代码无关,因为你还没有对其进行处理。

如果你添加数字,它会变成科学计数法:

splitToDigits(1234567849876543211521521251) // turns to 1.2345678498765432e+27

这是一个与JavaScript精度有关的问题。就是这样 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接