为什么JavaScript的parseInt(0.0000005)会打印出"5"?

63

我读了一篇关于JavaScript parseInt的文章,其中提到了这个问题:

parseInt(0.5);      // => 0
parseInt(0.05);     // => 0
parseInt(0.005);    // => 0
parseInt(0.0005);   // => 0
parseInt(0.00005);  // => 0
parseInt(0.000005); // => 0

parseInt(0.0000005); // => 5

为什么会发生这种情况?


7
在这个问题和答案中,可能应该强烈建议不要对不是字符串的x使用parseInt(x)。如果您已经有一个数字,那么您可能需要使用Math.round()Math.floor()等函数。这里的示例表明,通常获得合理的输出只是运气而已。 - jcalz
2
虽然ESLint没有抱怨,但至少PhpStorm(对JavaScript和TypeScript也很有用)警告数字不能分配为字符串参数。 - Ingo Steinke
这是一个通常的谬误示例,即不检查输入值类型。此类隐式字符串转换的其他示例在此处进行了介绍 - https://alex-klaus.com/javascript-wat/ - Alex Klaus
3个回答

106

根据 ecmascript 标准

parseInt 函数会根据指定的基数对string参数内容的解释生成一个整型的Number

Part1 - 将0.0000005转换为string

parseInt函数的第一步是将输入值转换成string

19.2.5 parseInt ( string, radix )

调用parseInt函数时,执行以下操作:

  1. 令inputString为? ToString(string)。
  2. 令S为! TrimString(inputString, start)。

...

在每种情况下,字符串输出如下:

String(0.5);      // => '0.5'
String(0.05);     // => '0.05'
String(0.005);    // => '0.005'
String(0.0005);   // => '0.0005' 
String(0.00005);  // => '0.00005'
String(0.000005); // => '0.000005'

String(0.0000005); // => '5e-7'

第二部分 - 将5e-7转换为整数

因此,当我们使用parseInt(0.0000005)时,它等同于parseInt('5e-7'),根据定义:

parseInt可能将字符串的仅前导部分解释为整数值; 它会忽略任何无法解释为整数符号的代码单元,并且不会指示忽略了任何这样的代码单元。

因此,答案仅返回5,因为它是直到非数字字符e的唯一数字字符,所以其余的e-7将被舍弃。

感谢@jcalz提醒:

不要对不是stringx使用parseInt(x)。如果您已经有一个number,可能需要使用Math.round()Math.floor() 或其他函数。


9
(这更像是一条长评论,而不是一个竞争性的答案。)
在将值作为数字类型传递给parseInt时,会发生意想不到的转换导致这种奇怪的效果-在这种情况下,似乎解释器(或解释器或驱动JS的任何东西)会自动将数字转换为字符串,因为函数参数的预期类型是字符串类型。
不幸的是,该数字转换为字符串的函数在受到长度限制时,会优先选择工程数格式。
此外,转换可能会导致精度丢失,这是每个程序员在处理小数(非整数)时都必须注意的问题。 如果你记得自己把要解析的值放进字符串里,那么你就不会得到这样意外的结果:
let n = '0.0000005';
console.log(parseInt(n))

将输出所需的0。

教训:

  • 尽可能避免隐式类型转换。
  • 避免使用类似于parseInt的函数,这些函数无法让您知道要解析的字符串是否有多余的不适配数据。例如,将"x"或"1x"解析为整数都应告诉您这不是一个正确的整数。在这方面,parseInt表现出不良行为,因为它忽略了字符串中的额外数据,并未告诉我们。一个好的解析器函数要么告诉你它停在哪里(以便你可以检查是否还有垃圾),要么在发现意外数据时失败。

-2

请尊重数据类型!

在Chrome控制台中:

parseInt("0.5");
0
parseInt("0.05");
0
parseInt("0.005");
0
parseInt("0.0005");
0
parseInt("0.00005");
0
parseInt("0.000005");
0
parseInt("0.0000005");
0
parseInt("0.00000005");
0
parseInt("0.000000005");
0


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