
parseInt() 不总是正确地转换为整数
在 JavaScript 中,所有的数字都是浮点型的,整数是没有小数的浮点数。将一个数 n
转换为整数意味着找到接近 n
的整数。你可能认为 parseInt()
能处理这项任务,但是它不能。至少,不总是有效。
parseInt() 如何工作
parseInt()
有如下定义:
parseInt(value, radix?)
它将 value
转换为字符串,然后忽略前导空格并找寻尽可能连续的整数位。
关于基数(radix)
默认值为 10,如果 radix
缺省。除非 value
以 '0x' 或 '0X' 开头,这种情况下 radix
的值将默认为 16(十六进制数)。
parseInt('0xA'); // 10
如果 radix
已经设定为 16,那十六进制 前缀是可选的。
parseInt('0xA', 16); // 10
parseInt('A', 16); // 10
以上我们介绍了 ECMAScript 规范 定义的 parseInt()
行为。另外,一些引擎将以 0 为前缀的整数的 radix
设置为 8:
parseInt('010'); // 8
parseInt('0109'); // 8 // 忽略位数 ≥ 8
因此,最好总是明确的指定 radix
。
例子
一些例子:
parseInt(' 12', 10); // 12
parseInt('12**', 10); // 12
parseInt('12.34', 10); // 12
parseInt(12.34, 10); // 12
最后一个例子告诉我们可以使用 parseInt()
转换数字为整数。然而,这里有一个转换错误的例子:
parseInt(1000000000000000000000.5, 10); // 1
说明:parseInt
首先将参数转换为字符串。
String(1000000000000000000000.5); // '1e+21'
然后 parseInt
不识别 "e" 为整数位而停止解析 1 后面的内容。另一个例子:
parseInt(0.0000008, 10); // 8
//同理
String(0.0000008); // '8e-7'
这些限制了 parseInt()
的可用性。然而请注意,出现错误的正指数的数开始于 ±1e+21:
String(1e20); // '100000000000000000000'
String(1e21); //'1e+21'
这将远远超出 JavaScript 的整数范围 [−253, 253]
替代 parseInt() 的方法
函数
Math.trunc()
和toInteger()
、Math.round()
通常用于number
类型。 传入这些函数的参数会隐式转换为数字类型,所以:'80w' => NaN,这与parseInt()
不同。
Math.trunc()
ES6 中添加 Math.trunc()
函数用于截断数字的小数部分:
Math.trunc(80.6); // 80
Math.trunc('80.1'); // 80
Math.trunc('hello'); // NaN
Math.trunc(NaN); // NaN
Math.trunc(undefined); // NaN
关于 Math.trunc()
博客文章 "Javascript 中的数字截断" 的介绍更详细。
toInteger()
一个好的选择是使用下面的方法,toInteger()
操作来执行 ECMAScript 规范:
function toInteger(x) {
x = Number(x);
return x < 0 ? Math.ceil(x) : Math.floor(x);
}
这个方法简单地移除小数部分。例如:
toInteger(3.2); // 3
toInteger(3.5); // 3
toInteger(3.8); // 3
toInteger(-3.2); // -3
toInteger(-3.5); // -3
toInteger(-3.8); // -3
Math.round()
博客 "Integers and shift operators in JavaScript" 提到几个转换数字为整数的方法。一个好的选项 Math.round()
,其中 Math.round()
总是使用四舍五入的方式获取最近的整数:
Math.round(3.2); // 3
Math.round(3.5); // 4
Math.round(3.8); // 4
Math.round(-3.2); // -3
Math.round(-3.5); // -3
Math.round(-3.8); // -4
4 被认为最接近 3.5,而 -3 被认为最接近 -3.5。这与
parseInt()
行为不同。
扩展阅读
本文作者 Axel Rauschmayer,转载请注明来源链接:
原文链接:https://2ality.com/2013/01/parseint.html
本文链接:https://tie.pub/2019/06/parseint-does-not-always-correctly-convert-to-integer/