FAQ
Q: Why does 0.1 + 0.2 not equal 0.3?
This is a classic IEEE 754 precision issue. Decimal 0.1 and 0.2 cannot be represented exactly in binary floating point — just as decimal cannot represent 1/3 exactly. 0.1 in binary is an infinitely repeating fraction that gets truncated when stored, introducing a tiny rounding error. Adding two imprecise values preserves the error, yielding 0.30000000000000004 instead of 0.3. This behavior is not unique to JavaScript — it affects virtually every language that uses IEEE 754.
Q: What is JavaScript's MAX_SAFE_INTEGER and why?
Number.MAX_SAFE_INTEGER is 2⁵³ − 1 (i.e. 9007199254740991). IEEE 754 double-precision uses 52 bits for the mantissa, plus one implicit leading bit, giving 53 bits of significand. This means only integers up to 53 bits can be represented exactly. Beyond this range, consecutive integers map to the same floating-point representation — for example, 9007199254740992 === 9007199254740993 evaluates to true. Use BigInt for arbitrary-precision integer arithmetic.
Q: What is −0? Is it different from 0?
IEEE 754 stores the sign bit separately, so both +0 and −0 exist. In most operations they behave identically: −0 === +0 is true, and −0 + 0 equals 0. However, they can be distinguished in special cases: 1 / +0 is Infinity, while 1 / −0 is −Infinity. You can also use Object.is(−0, 0) which returns false. Negative zero preserves directional information — e.g. a value approaching zero from the negative side.
Q: What is NaN, and why does NaN !== NaN?
NaN (Not a Number) is a special IEEE 754 value representing undefined or unrepresentable math results, such as 0 / 0 or Math.sqrt(-1). The standard specifies that NaN is not equal to any value, including itself. This is a deliberate design choice to prevent misleading equality comparisons on meaningless results. In JavaScript, use Number.isNaN() for reliable detection — avoid the global isNaN(), which coerces its argument and can produce unexpected results.
Q: How can floating-point precision issues be solved?
Several approaches exist. For financial calculations, scale decimals to integers (e.g. work in cents instead of dollars) to avoid float arithmetic altogether. For arbitrary precision, use libraries like decimal.js or big.js, which perform decimal arithmetic via string representation. When comparing floats, avoid ===; instead check whether the absolute difference is smaller than a tolerance (e.g. Number.EPSILON). The right approach depends on your precision requirements and performance constraints.