parseInt()用指数错误地解析数字文字

时间:2015-05-11 06:30:21

标签: javascript node.js numbers parseint

我刚刚观察到parseInt函数在整数(包含e字符的数字)的情况下不会处理小数。

让我们举个例子:-3.67394039744206e-15

> parseInt(-3.67394039744206e-15)
-3
> -3.67394039744206e-15.toFixed(19)
-3.6739e-15
> -3.67394039744206e-15.toFixed(2)
-0
> Math.round(-3.67394039744206e-15)
0

我预计parseInt也会返回0。在较低级别发生了什么?为什么parseInt在这种情况下返回3(源代码中的一些片段会受到赞赏)?

在此示例中,我使用node v0.12.1,但我希望在浏览器和其他JavaScript引擎中也会发生同样的情况。

6 个答案:

答案 0 :(得分:16)

我认为原因是parseInt通过调用将返回"-3.67394039744206e-15"的{​​{3}}将传递的值转换为字符串,然后解析它以便它将考虑-3并返回它

ToString

  

parseInt函数将其第一个参数转换为字符串,即parses   它,并返回一个整数或NaN

答案 1 :(得分:4)

parseInt(-3.67394039744206e-15) === -3

parseInt function期望一个字符串作为第一个参数。如果参数不是字符串,JavaScript将在场景后面调用toString方法。所以表达式评估如下:

(-3.67394039744206e-15).toString()
// "-3.67394039744206e-15"
parseInt("-3.67394039744206e-15")
// -3

-3.67394039744206e-15.toFixed(19) === -3.6739e-15

此表达式被解析为:

  • Unary - operator
  • 数字文字3.67394039744206e-15
  • .toFixed() - 属性访问者,属性名称和函数调用

解析数字文字的方式是described here。有趣的是, +/-不是数字文字的一部分。所以我们有:

// property accessor has higher precedence than unary - operator
3.67394039744206e-15.toFixed(19)
// "0.0000000000000036739"
-"0.0000000000000036739"
// -3.6739e-15

同样适用于-3.67394039744206e-15.toFixed(2)

3.67394039744206e-15.toFixed(2)
// "0.00"
-"0.00"
// -0

答案 2 :(得分:3)

如果解析后的字符串(剥离+/-符号)包含的任何字符不是基数(在您的情况下为10),则会创建一个子字符串,其中包含所有其他字符,然后才会丢弃这些无法识别的字符。

-3.67394039744206e-15的情况下,转换开始并且基数被确定为基数10 - >转换发生直到遇到'。'这不是基数10中的有效字符 - 因此,有效地,转换发生在3,它给出值3然后应用符号,因此-3。

对于实施逻辑 - http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.2.2

更多例子 -



alert(parseInt("2711e2", 16));
alert(parseInt("2711e2", 10));




注意:

基数从10开始。

如果第一个字符是' 0',则会切换到第8个字符。

如果下一个字符是' x',则会切换到16位。

答案 3 :(得分:1)

它尝试将字符串解析为整数。我的怀疑是你的花车首先被送到琴弦。然后,它不是解析整个值然后舍入,而是使用逐字符解析函数,并在它到达第一个小数点时停止,忽略任何小数位或指数。

此处的一些示例http://www.w3schools.com/jsref/jsref_parseint.asp

答案 4 :(得分:0)

parseInt的目的是解析字符串而不是数字:

  

parseInt()函数解析一个字符串参数并返回一个   指定基数的整数(数学数字的底数   系统)。

然后parseInt调用函数ToString,其中所有非数字字符都将被忽略。

您可以使用Math.round来解析字符串,然后将数字四舍五入到最接近的整数:

Math.round("12.2e-2") === 0 //true

答案 5 :(得分:0)

Math.round(“ 12.2e-2”)可以根据该值向上或向下取整。因此可能会导致问题。

新Number(“ 3.2343e-10”).toFixed(0)可以解决此问题。