整数类型(integer)在javascript经常会导致一些奇怪的问题。在ecmascript的规范中,他们只存在于概念中:
所有的数字都是浮点数,并且整数只是没有一组没有小数的数字。
在这篇博客中,我会解释如何去检查某个值是否为整型。
ecmascript 5
在es5中有很多方法你可以使用。有时侯,你可能想用自己的方法:一个isinteger(x)的函数,如果是整型返回true,否则返回false.
让我们看看一些例子。
通过余数检查
你可以使用余数运算(%),将一个数字按1求余,看看余数是不是0。
function isinteger(x) { return x % 1 === 0;}
我喜欢这个方法,因为它非常简单,而且有效。
> isinteger(17)true> isinteger(17.13)false
在操作余数运算时你得小心一点,因为结果取决于第一个数的符号,如果是正的,结果就是正的;否则就是负的。
> 3.5 % 10.5> -3.5 % 1-0.5
然后,我们也可以检查0,这其实不是一个问题。但问题是:这个方法对非数字也会返回true,因为 % 会将它转换成数字:
> isinteger('')true> isinteger('33')true> isinteger(false)true> isinteger(true)true
可以通过很简单的类型检查来解决:
function isinteger(x) { return (typeof x === 'number') && (x % 1 === 0);}
通过math.round() 如果一个数字取整以后还跟之前的值一样,那么它就是整数。在javascript中可以通过math.round()来检查:
function isinteger(x) { return math.round(x) === x;}
这个方法也不错
> isinteger(17)true> isinteger(17.13)false
它也可以判断非数字,因为math.round()总是返回数字,并且===只有当类型一样时才返回true.
> isinteger('')false
如果你想让代码更清晰一点,你可以添加类型检查(就是我们在之前版本做的)。另外,math.floor()和math.ceil()可以像math.round()一样工作。 通过位操作检查 位操作符提供另外一种“取整”的方法:
function isinteger(x) { return (x | 0) === x;}
这个解决方案(跟其它位运算一样)有一个缺陷:它无法处理超过32位的数字。
> isinteger(math.pow(2, 32))false
通过parseint()检查 parseint()也提供了跟math.round()类似将数字转换成整型的方法。 让我们看看这个方法为什么不错。
function isinteger(x) { return parseint(x, 10) === x;}
像math.round()解决方案一样,它也可以处理非数字的情况,但是它也不能正确地处理所有的整型数字:
> isinteger(1000000000000000000000)false
为什么?parseint()在解析整数之前强迫将第一个参数解析成字符串。因此使用这种方法将数字转换成整型不是一个好的选择。
> parseint(1000000000000000000000, 10)1> string(1000000000000000000000)'1e+21'
就像上面那样,parseint()在解析'1e+21'时在1处停止处理了,所以它才会返回1. ecmascript 6 对于math.round()扔补充,es6提供了另外一个将数字转换成整型的方法:math.trunc()。该函数会移除数字的小数部分。
> math.trunc(4.1)4> math.trunc(4.9)4> math.trunc(-4.1)-4> math.trunc(-4.9)-4
此外,ecmascript6不需要去处理检查整数那些琐碎的任务,因为它带有一个内置函数 number.isinteger()。
