← Back to Chapters

JavaScript Numbers & BigInt

? JavaScript Numbers & BigInt

? Quick Overview

In JavaScript, all regular numeric values (integers and decimals) use the Number type, which is implemented using the IEEE 754 double-precision 64-bit format. This means JavaScript does not have a separate integer type at the language level.

For integers that go beyond the safe range of Number, JavaScript provides the BigInt type. BigInt can represent arbitrarily large whole numbers, which is useful in domains like cryptography, financial systems, and large ID handling.

? Key Concepts

  • Number is the default numeric type for integers and floating-point values.
  • Numbers are stored using IEEE 754 double precision (64-bit floating point).
  • BigInt represents integers beyond Number.MAX_SAFE_INTEGER.
  • BigInt values are created with an n suffix or the BigInt() constructor.
  • Safe integers lie between Number.MIN_SAFE_INTEGER and Number.MAX_SAFE_INTEGER.
  • Special numeric values include Infinity, -Infinity, and NaN.
  • BigInt and Number cannot be mixed in arithmetic without explicit conversion.

? Syntax & Theory

? Number literals

Numbers can be written as simple integer or decimal literals. JavaScript will still treat them as Number values internally.

? View Number literal example
let intNum = 42;          // Integer number
let floatNum = 3.14159;   // Floating-point number

There is no separate integer type: both intNum and floatNum are of type number.

? BigInt syntax

BigInt is used when you need integers larger than Number.MAX_SAFE_INTEGER (2^53 - 1). You can create BigInt values using a literal with an n suffix or by using the BigInt() constructor.

? View BigInt creation example
const bigInt1 = 9007199254740991n;                 // BigInt literal
const bigInt2 = BigInt("900719925474099123456789"); // Using constructor

BigInt values can represent extremely large integers without losing precision, as long as you keep them as BigInt and do not convert them to Number.

? Number methods & parsing

The Number object and number instances provide useful methods to format and convert numbers.

  • toFixed(digits) – Fixed number of decimal places (returns a string).
  • toExponential(digits) – Exponential notation as a string.
  • toPrecision(precision) – Total number of significant digits.
  • toString(base) – String representation (optionally with base from 2 to 36).
  • parseInt(string) – Parses a string and returns an integer.
  • parseFloat(string) – Parses a string and returns a floating-point number.
? View Number methods example
let num = 123.456789;

console.log(num.toFixed(2));         
// "123.46" - rounds and formats with 2 decimals

console.log(num.toExponential(3));  
// "1.235e+2" - exponential notation with 3 decimals

console.log(num.toPrecision(5));     
// "123.46" - total 5 digits

console.log(num.toString());         
// "123.456789" - string representation

console.log(num.toString(16));       
// "7b.74bc6a7ef9db22d0" - hexadecimal string

console.log(parseInt("42px"));       
// 42 - parses integer from string

console.log(parseFloat("3.14 meters"));
// 3.14 - parses float from string

? Numeric limits & special values

The global Number object exposes properties that describe the numeric limits and special values JavaScript can represent.

  • Number.MAX_VALUE – Largest positive representable number (~1.79e+308).
  • Number.MIN_VALUE – Smallest positive representable number (~5e-324).
  • Number.MAX_SAFE_INTEGER – Largest safe integer (2^53 - 1).
  • Number.MIN_SAFE_INTEGER – Smallest safe integer (-2^53 + 1).
  • Number.POSITIVE_INFINITY – Positive infinity.
  • Number.NEGATIVE_INFINITY – Negative infinity.
  • Number.NaN – "Not a Number", used when numeric conversion fails.
? View Number properties example
console.log(Number.MAX_VALUE);           // 1.7976931348623157e+308
console.log(Number.MIN_VALUE);           // 5e-324
console.log(Number.MAX_SAFE_INTEGER);    // 9007199254740991
console.log(Number.MIN_SAFE_INTEGER);    // -9007199254740991
console.log(Number.POSITIVE_INFINITY);   // Infinity
console.log(Number.NEGATIVE_INFINITY);   // -Infinity
console.log(Number.NaN);                 // NaN

// Checking for NaN properly
let val = Number("abc");
console.log(isNaN(val));                 // true

? BigInt operations

BigInt supports most arithmetic and comparison operators, similar to Number, but only for integers.

  • Arithmetic: +, -, *, /, %, **
  • Comparison: <, >, ===, etc.
  • Conversion: toString() to get a string representation.
? View BigInt operations example
const big1 = 123456789012345678901234567890n;
const big2 = 100000000000000000000000000000n;

console.log(big1 + big2);     
// 223456789012345678901234567890n

console.log(big1 * 2n);       
// 246913578024691357802469135780n

console.log(big1.toString()); 
// "123456789012345678901234567890"

? Converting between Number and BigInt

You cannot mix Number and BigInt directly in arithmetic expressions. Explicit conversion is required on one side.

? View Number & BigInt conversion example
let n1 = 10n;
let n2 = 20;

// console.log(n1 + n2);   // ❌ TypeError: Cannot mix BigInt and other types
// console.log(n1 + 20);   // ❌ TypeError

// Convert Number to BigInt:
console.log(n1 + BigInt(20)); 
// 30n

// Convert BigInt to Number:
console.log(Number(n1) + 20); 
// 30

? Use Cases

  • Use Number for most everyday calculations, UI values, measurements, and when dealing with decimals.
  • Use BigInt when working with IDs, counters, or cryptographic values that may exceed the safe integer range.
  • Avoid using BigInt for fractional values—BigInt is only for whole numbers.

? Output & Explanation

? What the console logs show

  • Formatting: toFixed(2) converts 123.456789 into the string "123.46" by rounding to 2 decimal places.
  • Exponential form: toExponential(3) returns something like "1.235e+2", which is scientific notation.
  • Precision: toPrecision(5) keeps 5 significant digits, again resulting in "123.46".
  • Bases: num.toString(16) converts the number to a hexadecimal string representation.
  • Parsing: parseInt("42px") returns 42, stopping when it hits a non-digit character.
  • Special values: Number("abc") gives NaN, and isNaN() correctly detects that it is not a valid number.
  • BigInt arithmetic: Operations like big1 + big2 or big1 * 2n return BigInt results without precision loss even for huge integers.
  • Conversions: Converting between Number and BigInt lets you bridge both worlds, but you must do it explicitly.

? Tips & Best Practices

  • Use toFixed() to format decimals when displaying numbers to users (e.g., prices).
  • Use BigInt for very large integers or counters outside the safe range.
  • Be careful with isNaN(). Prefer Number.isNaN() when working with numeric results to avoid unexpected coercions.
  • Watch out for floating-point precision issues (e.g., 0.1 + 0.2 !== 0.3 exactly).
  • Do not mix Number and BigInt arithmetic without explicit conversion.

? Try It Yourself

  • Declare several Number values (integers and decimals) and log their types with typeof.
  • Create a few BigInt values using both literals (with n) and the BigInt() constructor.
  • Format numbers using toFixed(), toExponential(), and toPrecision(), and observe the differences.
  • Use parseInt() and parseFloat() on strings like "100px", "3.5kg", and "abc".
  • Experiment with conversions between Number and BigInt and see what happens if you try to mix them without conversion.
  • Find out at which point adding 1 to a large Number no longer changes its value, and then solve the same problem using BigInt.