Checking whether a value is an integer in JavaScript

Integers lead an odd life in JavaScript. In the ECMAScript specification, they only exist conceptually: All numbers are always floating point and integers are ranges of numbers without decimal fractions (for details, consult “Integers in JavaScript” in “Speaking JavaScript”). In this blog post, I explain how to check whether a value is an integer.




ECMAScript 5

There are many ways in which you could implement this check. At this moment, you may want to take a break and try to write your own solution: a function isInteger(x) that returns true if x is an integer and false, otherwise.


Let’s look at a few examples.


Checking via the remainder operator

One can use the remainder operator (%) to express the fact that a number is an integer if the remainder of dividing it by 1 is 0.



function isInteger(x) {
return x % 1 === 0;
}

I like this solution, because it is quite self-descriptive. It usually works as expected:



> isInteger(17)
true
> isInteger(17.13)
false

You have to be careful with the remainder operator, because the first operand determines the sign of the result: if it is positive, the result is positive, if it is negative, the result is negative.



> 3.5 % 1
0.5
> -3.5 % 1
-0.5

However, we are checking for zero, so that’s not an issue here. One problem remains: this function can return true for non-numbers, because % coerces its operands to numbers:



> isInteger('')
true
> isInteger('33')
true
> isInteger(false)
true
> isInteger(true)
true

That can be easily fixed by adding a type check:



function isInteger(x) {
return (typeof x === 'number') && (x % 1 === 0);
}

Checking via Math.round()

A number is an integer if it remains the same after being rounded to the “closest” integer. Implemented as a check in JavaScript, via Math.round():



function isInteger(x) {
return Math.round(x) === x;
}

This function works as it should:



> isInteger(17)
true
> isInteger(17.13)
false

It also handles non-numbers correctly, because Math.round() always returns numbers and === only returns true if both operands have the same type.



> isInteger('')
false

If you wanted to make the code more explicit, you could add a type check (like we did in the previous solution). Furthermore, Math.floor() and Math.ceil() work just as well as Math.round().


Checking via bitwise operators

Bitwise operators provide another way of converting a number to a “close” integer:



function isInteger(x) {
return (x | 0) === x;
}

This solution (along with other solutions based on bitwise operators) has one disadvantage: it can’t handle numbers beyond 32 bits.



> isInteger(Math.pow(2, 32))
false

Checking via parseInt()

parseInt() also converts numbers to integers and can be used similarly to Math.round(). Let’s find out whether that is a good idea.



function isInteger(x) {
return parseInt(x, 10) === x;
}

Like the Math.round() solution, this implementation handles non-numbers well, but it does not correctly identify all numbers as integers:



> isInteger(1000000000000000000000)
false

Why? parseInt() coerces its first parameter to string before parsing digits. It is not a good choice for converting numbers to integers.



> parseInt(1000000000000000000000, 10)
1
> String(1000000000000000000000)
'1e+21'

Above, parseInt() stops parsing '1e+21' before the first non-digit, e, which is why it returns 1.


Other solutions

I received a few more interesting solutions via Twitter, check them out.


ECMAScript 6

Complementing Math.round() et al., ECMAScript 6 provides an additional way of converting numbers to integers: Math.trunc(). That function removes a number’s decimal fraction:



> Math.trunc(4.1)
4
> Math.trunc(4.9)
4
> Math.trunc(-4.1)
-4
> Math.trunc(-4.9)
-4

Furthermore, ECMAScript 6 makes the task of checking for integers trivial, because it comes with a built-in function Number.isInteger().


Further reading


  • Converting to Integer” (in “Speaking JavaScript”) covers the most common ways of converting numbers to integers.

  • Safe Integers” (in “Speaking JavaScript”) explains what range of integers can be safely used in JavaScript and what “safely used” means.


Comments

Popular posts from this blog

Steve Lopez and the Importance of Newspapers

Ideas for fixing unconnected computing

Omar to kill me