Number, Math & BigInt
Number, Math, and the two global parse helpers, backed by IEEE-754 doubles with an exact-i64 fast path where the inputs are integers. The remaining divergence is narrow: the trig/log/hyperbolic family comes from the platform libm, which can differ from V8's fdlibm in the last binary digit. Everything else — toFixed/toPrecision/toExponential and every toString radix, exponent formatting (min-digit, `e+5`), the constants, parseFloat's `"0x10"` → `0` hex-prefix rule, parseInt's hex auto-detect, and the bit ops — matches real JS.
Number.isInteger(x)
ExactReports whether x is a finite integer value — floor(x) == x gated on a finiteness check, so ±Infinity and NaN are false, matching real JS.
Number.isFinite(x)
ExactTrue when x is a finite number (not NaN, not ±Infinity). Unlike the global isFinite, does not coerce non-number arguments.
Number.isNaN(x)
ExactTrue only when x is the NaN value itself — the non-coercing sibling of the global isNaN.
Number.isSafeInteger(x)
ExactTrue when x is an integer that round-trips exactly through a double — i.e. within ±(2^53 − 1).
Number.parseInt(s)
ExactParses a leading integer out of s. Returns a double (as real JS), so a no-digits input is a real NaN via an endptr-checked strtoll. With radix omitted, auto-detects base 16 for a "0x"/"0X" prefix and base 10 otherwise (no octal auto-detect).
Number.parseFloat(s)
supportedParses a leading floating-point number out of s. A "0x10" hex prefix reads only its leading 0 → 0 (real parseFloat, unlike Number("0x10") → 16). A no-conversion input returns a real NaN via the endptr check. Only the exact word "Infinity" parses to Infinity ("inf" is NaN).
Number.MAX_SAFE_INTEGER
ExactThe largest integer that round-trips through a double, 2^53 − 1 (9007199254740991).
Number.MIN_SAFE_INTEGER
ExactThe most-negative safe integer, −(2^53 − 1).
Number.EPSILON
ExactThe difference between 1 and the smallest double greater than 1, 2^-52.
Number.MAX_VALUE
ExactThe largest representable positive double, roughly 1.7976931348623157e+308.
Number.MIN_VALUE
ExactThe smallest representable positive (subnormal) double, roughly 5e-324.
Number.POSITIVE_INFINITY
ExactThe +Infinity value.
Number.NEGATIVE_INFINITY
ExactThe −Infinity value.
Number.NaN
ExactThe NaN value, as a Number static property.
Number.prototype.toFixed(n)
ExactFormats x with a fixed number of digits after the decimal point, by the spec's algorithm over the exact value: an exact tie rounds to the larger value ((2.5).toFixed(0) is "3"), |x| ≥ 1e21 gives String(x), and a digit count outside 0..100 throws a RangeError. The digits argument is optional and defaults to 0.
Number.prototype.toString(radix?)
ExactRenders x as a string. The default (and radix 10) is exactly String(x) — the shortest round-trip decimal; any other base runs V8's own algorithm, the fraction to the double's precision, matching Node digit for digit. A radix outside 2..36 throws a RangeError.
Number.prototype.toPrecision(n)
ExactFormats x to the given number of significant digits by the spec's algorithm: exact rounding with ties to the larger value, exponential notation below 1e-6 or at 10^precision and up, and a RangeError outside 1..100. With the precision omitted, toPrecision() is exactly String(x).
Number.prototype.toExponential(n?)
ExactFormats x in exponential notation by the spec's algorithm over the exact value (ties to the larger value, e+4 minimum-digit exponents); with no argument, the shortest round-trip mantissa (12345 → 1.2345e+4), as in Node.
parseInt(s, radix?) (global)
ExactThe global parseInt — same runtime as Number.parseInt. A no-digits input yields a real NaN; with radix omitted, hex auto-detect for a "0x" prefix, base 10 otherwise.
parseFloat(s) (global)
supportedThe global parseFloat — same runtime as Number.parseFloat, including the "0x10" → 0 hex-prefix rule. A no-conversion input yields a real NaN; only the exact word "Infinity" parses to Infinity.
isNaN(x) (global)
ExactThe global isNaN — true when x is NaN.
isFinite(x) (global)
ExactThe global isFinite — true when x is finite.
Math.floor/ceil/round/trunc
ExactThe four rounding modes. A float input stays a double end-to-end, so NaN/±Infinity pass through unchanged; Math.round uses JS's tie-toward-+Infinity (Math.round(-4.5) === -4), including the -0 result for Math.round(-0.5). An integer input keeps the exact-i64 path.
console.log(Math.floor(-3.2)) // -4
console.log(Math.ceil(3.2)) // 4
console.log(Math.round(3.5)) // 4
console.log(Math.trunc(-3.9)) // -3Math.abs
ExactAbsolute value, preserving the integer fast path for integer inputs.
console.log(Math.abs(-10)) // 10Math.sqrt/pow/hypot
ExactSquare root, exponentiation, and the Euclidean-norm helper.
console.log(Math.pow(2.0, 10.0)) // 1024
console.log(Math.sqrt(9.0)) // 3
console.log(Math.hypot(3.0, 4.0)) // 5Math.log/log2/log10
Works, with caveatsNatural, base-2, and base-10 logarithms.
console.log(Math.floor(Math.log2(8.0))) // 3
console.log(Math.floor(Math.log10(1000.0))) // 3Math.sin/cos/tan
Works, with caveatsThe primary trigonometric functions (radians).
const sinHalf = Math.sin(Math.PI / 2.0)
console.log(Math.round(sinHalf)) // 1Math.min/max
ExactAny float argument promotes the fold to llvm.minimum/llvm.maximum — NaN propagates and -0.0 orders below +0.0, as the JS spec; all-integer calls stay exact i64.
console.log(Math.min(1, 5, 3)) // 1
console.log(Math.max(1, 5, 3)) // 5Math.sign
ExactThe float path returns ±1.0 or the input itself (NaN stays NaN, a signed zero keeps its sign); the integer path stays exact i64.
console.log(Math.sign(42)) // 1
console.log(Math.sign(-7)) // -1
console.log(Math.sign(0)) // 0Math.random()
ExactReturns a float in [0, 1).
const roll = Math.floor(Math.random() * 6.0)
const rollOk = roll >= 0 && roll < 6
console.log(rollOk) // 1Math.PI/E/LN2/LN10/SQRT2/LOG2E/LOG10E
ExactThe standard Math constants.
console.log(Math.PI) // 3.141592653589793
console.log(Math.E) // 2.718281828459045
console.log(Math.SQRT2) // 1.4142135623730951Math.cbrt/expm1/log1p
Works, with caveatscbrt uses a deterministic, correctly-rounded fdlibm implementation (@__kml_cbrt) rather than platform libm, whose runtime cbrt is not reliably correctly-rounded and diverged by OS (glibc cbrt(27) gave 3.0000000000000004); expm1/log1p delegate to libm.
console.log(Math.cbrt(27.0)) // 3
console.log(Math.expm1(0.0)) // 0
console.log(Math.log1p(0.0)) // 0Math.asin/acos/atan/atan2
Works, with caveatsThe inverse trigonometric functions.
console.log(Math.acos(1.0)) // 0
console.log(Math.round(Math.atan2(1.0, 1.0) * 4.0)) // 3Math.sinh/cosh/tanh
Works, with caveatsThe hyperbolic functions.
console.log(Math.sinh(0.0)) // 0
console.log(Math.cosh(0.0)) // 1
console.log(Math.tanh(0.0)) // 0Math.exp and Math.asinh/acosh/atanh
Works, with caveatsThe exponential function and the inverse hyperbolic functions.
console.log(Math.exp(0)) // 1
console.log(Math.acosh(1)) // 0
console.log(Math.atanh(0)) // 0Math.clz32/fround/imul
Exactclz32 via LLVM's own llvm.ctlz.i32 intrinsic; fround via an fptrunc/fpext float32 round-trip; imul via 32-bit mul + sign-extend, giving real 32-bit-wraparound integer multiplication distinct from plain *'s double-precision result.
console.log(Math.clz32(1)) // 31
console.log(Math.imul(3, 4)) // 12
console.log(Math.fround(5.5)) // 5.5