JavaScript Number Type: Complete Guide

Understand the JavaScript Number type, its limits, special values like NaN and Infinity, and how floating-point arithmetic works in practice.

5 min read

JavaScript has exactly one numeric type: Number. It handles integers, decimals, and special values like Infinity and NaN all within the same type. Unlike languages such as Java or C that have separate int, float, and double types, JavaScript uses a single 64-bit format called IEEE 754 double-precision floating-point.

javascriptjavascript
console.log(typeof 42);
console.log(typeof 3.14);
console.log(typeof NaN);
console.log(typeof Infinity);

All four print "number". There is no separate integer type and no separate decimal type. Everything is just Number.

This single-type design simplifies most code but comes with important limits. You need to understand the safe integer range and floating-point behavior to avoid subtle bugs. For string-to-number conversion, see the guide to parseInt, parseFloat, and Number.

Integer limits

Because Number uses 64 bits, it cannot represent every possible integer. The safe integer range is from -(2^53 - 1) to 2^53 - 1:

javascriptjavascript
console.log(Number.MAX_SAFE_INTEGER);
console.log(Number.MIN_SAFE_INTEGER);

This prints 9007199254740991 and -9007199254740991. Within this range, integer arithmetic is exact and every value can be represented precisely. Beyond this boundary, integers start losing precision because the 64-bit format runs out of room to keep them distinct:

javascriptjavascript
const big = 9007199254740992;
console.log(big === big + 1);

This prints true, which is mathematically impossible. The number 9007199254740992 is too large to represent distinctly from 9007199254740993 in the 64-bit format, so adding 1 does nothing.

For integers larger than MAX_SAFE_INTEGER, JavaScript provides the BigInt type:

javascriptjavascript
const huge = 9007199254740993n;
console.log(huge + 1n);

The n suffix creates a BigInt, which has arbitrary precision. BigInt is a separate type from Number and cannot be mixed with Number in arithmetic without explicit conversion.

Floating-point quirks

The most famous JavaScript Number quirk is that 0.1 + 0.2 does not equal 0.3:

javascriptjavascript
console.log(0.1 + 0.2);
console.log(0.1 + 0.2 === 0.3);

This prints 0.30000000000000004 and false. The values 0.1, 0.2, and 0.3 cannot be represented exactly in binary floating-point. The hardware uses the closest approximation, and when you add two approximations, the error compounds.

For financial calculations or any situation requiring exact decimals, work in integers and divide at the end:

javascriptjavascript
const total = (10 + 20) / 100;
console.log(total);

This prints 0.3 exactly. The trick is to multiply everything by 100, do integer arithmetic, then convert back.

Special values: NaN

NaN stands for Not-a-Number. It is the result of mathematically invalid operations. For a deeper look at where NaN comes from and how to detect it, see the complete guide to NaN in JavaScript.

javascriptjavascript
console.log(0 / 0);
console.log(parseInt("hello"));
console.log(Math.sqrt(-1));

All three print NaN. Any operation that cannot produce a meaningful numeric result returns NaN.

NaN is the only JavaScript value that is not equal to itself:

javascriptjavascript
console.log(NaN === NaN);

This prints false, which shows that comparing a value directly to NaN never works, even when checking a value against itself. Because of this quirk, JavaScript provides a dedicated built-in function called Number.isNaN for detecting NaN values safely:

javascriptjavascript
console.log(Number.isNaN(NaN));
console.log(Number.isNaN("hello"));

The first prints true. The second prints false because "hello" is a string, not NaN. The older global isNaN function coerces its argument first and can produce misleading results, so prefer Number.isNaN.

Special values: Infinity

Infinity represents values beyond the maximum representable number. It appears when you divide by zero or exceed the upper limit:

javascriptjavascript
console.log(1 / 0);
console.log(-1 / 0);
console.log(Number.MAX_VALUE * 2);

The first prints Infinity. The second prints -Infinity. The third also prints Infinity because Number.MAX_VALUE times 2 exceeds the representable range.

Infinity behaves predictably in arithmetic. Any finite number plus Infinity is Infinity. Any finite number divided by Infinity is 0. Infinity minus Infinity, however, is NaN because the result is indeterminate.

Number properties and methods

The Number object provides useful constants and methods:

PropertyValue
Number.MAX_SAFE_INTEGER9007199254740991
Number.MIN_SAFE_INTEGER-9007199254740991
Number.MAX_VALUELargest representable positive number
Number.MIN_VALUESmallest representable positive number
Number.POSITIVE_INFINITYInfinity
Number.NEGATIVE_INFINITY-Infinity
Number.NaNNaN

Number also provides methods for formatting. toFixed returns a string with a fixed number of decimal places:

javascriptjavascript
const price = 59.976;
console.log(price.toFixed(2));

This prints "59.98", rounded to two decimal places. Note that toFixed returns a string, not a number. For display purposes this is usually what you want, but for further arithmetic you may need to convert the result back to a number with Number().

Common mistakes

Assuming 0.1 + 0.2 equals 0.3 is the most widespread Number gotcha. Use integer arithmetic or toFixed for display when exact decimals matter.

Comparing values to NaN directly never works because NaN !== NaN. Always use Number.isNaN for the check.

Treating toFixed as if it returns a number leads to type confusion. The expression (59.976).toFixed(2) + 1 returns "59.981" rather than 60.976 because the + operator performs string concatenation when one operand is a string.

Using parseInt on user input without a radix can produce unexpected octal interpretations. Always pass a radix of 10 to avoid that surprise.

Rune AI

Rune AI

Key Insights

  • JavaScript has one Number type for both integers and decimals.
  • Safe integers range from -(2^53 - 1) to 2^53 - 1.
  • 0.1 + 0.2 does not equal 0.3 due to floating-point representation.
  • NaN means Not-a-Number and is the result of invalid math operations.
  • Infinity and -Infinity represent values beyond the representable range.
  • Use BigInt for integers larger than Number.MAX_SAFE_INTEGER.
RunePowered by Rune AI

Frequently Asked Questions

Why does 0.1 + 0.2 not equal 0.3 in JavaScript?

JavaScript uses IEEE 754 double-precision floating-point, which cannot represent 0.1, 0.2, or 0.3 exactly. The sum 0.1 + 0.2 produces 0.30000000000000004. For precise decimal math, multiply by 100, do integer math, then divide.

What is the largest safe integer in JavaScript?

The largest safe integer is 9007199254740991, accessed as Number.MAX_SAFE_INTEGER. Beyond this value, integers lose precision because the Number type cannot represent them exactly.

Is there a separate integer type in JavaScript?

No. JavaScript has only one numeric type: Number. It represents both integers and floating-point values. For arbitrary-size integers, use the BigInt type introduced in ES2020.

Conclusion

JavaScript has a single Number type for all numeric values. It uses IEEE 754 double-precision floating-point, which means integers are safe up to 2^53 - 1, decimals can have precision quirks, and special values like NaN and Infinity exist. Understanding these limits helps you avoid common arithmetic bugs.