JavaScript Number Type
JavaScript uses the `Number` type for most numeric values, represented as IEEE 754 double-precision floating-point numbers. This design supports integers and fractions but introduces precision limits and special values such as `NaN` and `Infinity`.
In JavaScript, `number` is a primitive type used for ordinary integers and floating-point values. Unlike languages with separate integer and floating-point types, JavaScript uses the same `Number` type for both in most cases.
`Number` follows the IEEE 754 binary64 format. It provides roughly 15–16 decimal digits of precision, so some decimal fractions cannot be represented exactly in binary. This explains results such as `0.1 + 0.2` producing `0.30000000000000004`.
Safe integer arithmetic is limited to values from `Number.MIN_SAFE_INTEGER` through `Number.MAX_SAFE_INTEGER`, which are `-9007199254740991` and `9007199254740991`. Beyond this range, different integer values can become indistinguishable when represented as `Number`.
JavaScript also has special numeric values including `NaN`, `Infinity`, `-Infinity`, `-0`, and `Number.MAX_VALUE`. Use `Number.isNaN()` to specifically test for `NaN`, and `Number.isFinite()` when you need to ensure a value is a finite number.
For integers larger than the safe `Number` range, JavaScript provides `BigInt`. `BigInt` should be used deliberately because it does not mix directly with ordinary `Number` arithmetic without explicit conversion.
Key points
- `Number` represents ordinary integers and floating-point values using IEEE 754 binary64.
- Decimal fractions can have rounding errors because many cannot be represented exactly in binary.
- Only integers through `Number.MAX_SAFE_INTEGER` are guaranteed to be represented exactly.
- `NaN`, `Infinity`, `-Infinity`, and `-0` are valid numeric values.
- Use `BigInt` when exact integer arithmetic exceeds the safe `Number` range.
Interview questions
What are `NaN` and `Infinity`, and how should they be checked?
`NaN` represents a numeric result that is not a meaningful number, while `Infinity` and `-Infinity` represent positive and negative infinity. They are values within JavaScript's numeric system rather than exceptions by themselves. `Number.isNaN()` specifically tests for the numeric `NaN`, while `Number.isFinite()` checks that a value is a finite number. These methods avoid the implicit coercion performed by some older global checks.
What numeric type does JavaScript use for ordinary numbers?
JavaScript uses the `Number` primitive type for ordinary numeric values. Its representation is IEEE 754 binary64, also called double precision. The same type handles both integer-looking values and fractional values. This differs from languages that have distinct primitive integer and floating-point types.
Why does `0.1 + 0.2` not equal exactly `0.3`?
`Number` stores values in binary floating-point, and many decimal fractions do not have an exact binary representation. The stored approximations of `0.1` and `0.2` are therefore combined with a small rounding error. When the result is converted back to decimal for display, that error can become visible. For comparisons involving calculated decimal values, applications often use an appropriate tolerance or a decimal arithmetic strategy.
What is the safe integer range in JavaScript?
The safe integer range is from `Number.MIN_SAFE_INTEGER` through `Number.MAX_SAFE_INTEGER`, inclusive. The upper bound is `9007199254740991`, and the lower bound is its negative. Within this range, integer values can be represented exactly by `Number`. `Number.isSafeInteger()` can be used when code needs to validate that an integer is safely representable.
When would you choose `BigInt` instead of `Number`?
Use `BigInt` when exact integer arithmetic is required beyond the safe integer range of `Number`. Examples include some large identifiers, counters, and integer calculations where losing precision would be unacceptable. `BigInt` cannot be directly combined with `Number` using arithmetic operators, so code must keep the numeric domains consistent or convert explicitly. Conversion should be deliberate because converting a large `BigInt` to `Number` can lose precision.