🔥 Get 650+ Tech Books and Courses for \$3/m for 3 months

# Fun with JavaScript Numbers

Data types are an essential component of every programming language, and numbers are perhaps the most important of all data types. After all, computers are really just expensive calculators. Like any worthwhile programming language, JavaScript supports numerical data. However, like many other aspects of JavaScript, numbers have several intricacies which can bite you if you’re not careful. This article explores numerical data and some of its quirks.

Note: before reading this article, you should have a basic familiarity with JavaScript data types.

## The `Number` Type

In JavaScript, all numbers are represented using the Number data type. This includes integers, real numbers, hexadecimal numbers, and numbers written in scientific notation. The following example verifies this by applying the `typeof` operator to a variety of numbers. Each application of `typeof` in this example returns `number`.

``````typeof(100);
typeof(3.14);
typeof(7.89e2);``````

In the previous example, the numbers took on a variety of formats. However, internally, all JavaScript numbers are actually represented as IEEE 754 floating point data. This is important because it means that JavaScript has no concept of integers, despite the language’s `parseInt()` function. It also means that JavaScript math is not 100% accurate. For example, consider the following expression.

``(0.1 + 0.2) === 0.3``

If you are unfamiliar with floating point numbers, you would certainly expect this expression to evaluate to `true`. After all, 0.1 + 0.2 does equal 0.3. However, due to the way floating point numbers work, the sum is actually 0.30000000000000004. The difference is slight, but it is enough to cause the entire expression to evaluate as `false`.

## Positive and Negative Zero

Another quirk of the IEEE 754 standard is the signed zero. This results in two zeroes – a positive zero, +0, and a negative zero, -0. This may seem strange, but the fun is just beginning. Clearly, these are two distinct values, otherwise there would only be a single zero. However, if you display either of the zeroes, the sign is dropped. For example, the following code attempts to display the two zero values, side-by-side.

``````alert((+0) + " " + (-0));
// displays 0 0``````

To make matters worse, JavaScript’s comparison operators can’t seem to tell the two values apart either, as shown in the following example.

``````alert((+0 === -0));
// displays true
// displays false``````

There is a fairly simple workaround for this problem. In JavaScript, division by zero yields `Infinity`. Similarly, division by negative zero yields `-Infinity`. Therefore, to determine if a number is equal to -0, we must check that it is a zero, then perform division with it as the denominator, and check for `-Infinity` as shown below.

``````function isNegativeZero(x) {
return (x === 0 && (1/x) === -Infinity);
}``````

## Not-a-Number

JavaScript actually defines a number named Not-a-Number, or `NaN`. `NaN` is a falsy value that is used to represent non-numbers as numbers. This value is interesting because its very name precludes it from being a number, yet `typeof(NaN)` is `number`. `NaN` is also fun because it is the only value in JavaScript that does not equal itself. For example, the following code will return `false`.

``````alert((NaN === NaN));
// displays false``````

Instead of using the comparison operators, you can test for `NaN` using the `isNaN()` function, as shown below.

``````isNaN(1);
// returns false
isNaN(NaN);
// returns true``````

However, `isNaN()` is also fun because it can be misleading. If you pass in a value that can be coerced to a number, `isNaN()` will return `false`. In the following example, `isNaN()` is called with several values that are clearly not numbers. However, each call returns `false`.

``````isNaN(true);
isNaN(false);
isNaN("");
isNaN(null);
// all return false``````

A better way to check for `NaN` is by exploiting the fact that it is not equal to itself. The following function tests for `NaN` using strict inequality. This function will only return `true` for the value `NaN`.

``````function isNotANumber(x) {
return x !== x;
}``````

## Other Fun Times

There are a few other scenarios which can lead to problems with numbers. For starters, you should beware of old browsers that allow global properties like `Infinity`, `NaN`, and `undefined` to be redefined to new values. For example, the following code could create a lot of problems if `NaN` is used frequently. Luckily, modern browsers will ignore assignments to the previously mentioned properties. Strict mode goes one step further by turning these silent failures into errors.

``````NaN = 1;
...
isNaN(NaN);
// now returns false``````

Another fun to diagnose error comes from adding a number and a string. An example of this is shown below. In this case, string concatenation overrides addition. This causes `foo` to be converted to the string `"100"`. The final result is the string `"1001"`, which is much different from the expected value of 101. This type of error is more common than you think, and tends to occur when reading user input.

``````var foo = 100;
var bar = "1";