Free email newsletter: “ES.next News

2014-05-26

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.

No comments: