parseInt() 错误地解析带有指数的数字文字
parseInt() parses number literals with exponent incorrectly
我刚刚观察到 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
也会 return 0
。较低级别发生了什么?为什么 parseInt
return 3
在这种情况下(源代码中的一些片段将不胜感激)?
在这个例子中,我使用 node v0.12.1
,但我希望在浏览器和其他 JavaScript 引擎中发生同样的情况。
我认为原因是 parseInt
converts the passed value to string by calling ToString
它将 return "-3.67394039744206e-15"
,然后解析它所以它会考虑 -3
并将 return 它。
The parseInt function converts its first argument to a string, parses
it, and returns an integer or NaN
它尝试将字符串解析为整数。我怀疑您的花车首先被转换为字符串。然后,它不是解析整个值然后四舍五入,而是使用一个字符一个字符的解析函数,当它到达第一个小数点时将停止,忽略任何小数位或指数。
如果解析的字符串(去除 +/- 符号)包含任何非基数的字符(在您的情况下为 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 进制。
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
parseInt
的目的是解析字符串而不是数字:
The parseInt() function parses a string argument and returns an
integer of the specified radix (the base in mathematical numeral
systems).
并且parseInt
调用函数ToString
,其中忽略所有非数字字符。
您可以使用 Math.round
,它也解析字符串,将数字四舍五入为最接近的整数:
Math.round("12.2e-2") === 0 //true
Math.round("12.2e-2")
可能会根据值向上或向下舍入。因此可能会导致问题。
new Number("3.2343e-10").toFixed(0)
可能会解决问题。
我刚刚观察到 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
也会 return 0
。较低级别发生了什么?为什么 parseInt
return 3
在这种情况下(源代码中的一些片段将不胜感激)?
在这个例子中,我使用 node v0.12.1
,但我希望在浏览器和其他 JavaScript 引擎中发生同样的情况。
我认为原因是 parseInt
converts the passed value to string by calling ToString
它将 return "-3.67394039744206e-15"
,然后解析它所以它会考虑 -3
并将 return 它。
The parseInt function converts its first argument to a string, parses it, and returns an integer or NaN
它尝试将字符串解析为整数。我怀疑您的花车首先被转换为字符串。然后,它不是解析整个值然后四舍五入,而是使用一个字符一个字符的解析函数,当它到达第一个小数点时将停止,忽略任何小数位或指数。
如果解析的字符串(去除 +/- 符号)包含任何非基数的字符(在您的情况下为 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 进制。
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
parseInt
的目的是解析字符串而不是数字:
The parseInt() function parses a string argument and returns an integer of the specified radix (the base in mathematical numeral systems).
并且parseInt
调用函数ToString
,其中忽略所有非数字字符。
您可以使用 Math.round
,它也解析字符串,将数字四舍五入为最接近的整数:
Math.round("12.2e-2") === 0 //true
Math.round("12.2e-2")
可能会根据值向上或向下舍入。因此可能会导致问题。
new Number("3.2343e-10").toFixed(0)
可能会解决问题。