Javascript Numbers Deep Dive: BigInt, Math and Date Object & Performance Explained

Sangy KSangy K
7 min read

We've already taken a tour through Javascript's number basics β€” integers, floats, numeric literals, and why 0.1 + 0.2 !== 0.3 still haunts beginners.

Now it's time to go deeper. 🀿

In this article, we'll explore the full power of Javascript numbers β€” from the Math object and its hidden gems to BigInt for massive integers, dealing with timestamps and currency, and even a few performance hacks.

By the end, we'll have the confidence to handle all number-related tasks like seasoned developers.

Let's dive in! πŸš€

Javascript's built-in Utility Objects

A Javascript built-in utility object is a feature that the language provides out of the box β€” ready to use, no extra setup or libraries needed.

Think of it like a toolkit that comes with the language itself. For example:

  • The Math object is a built-in utility for math-related tasks β€” we don't have to install or import anything; we call Math.random() or Math.round().

  • Date, JSON, and Intl are other built-in utilities that handle dates, data conversion, and internationalisation.

Why does it matter?

These utilities are optimised, reliable, and standardised across browsers. Instead of reinventing the wheel, we can utilise existing tools to get things done faster and with fewer bugs.

πŸ“ The Math Object: Our Numeric Toolbox

Javascript gives us the Math object, a built-in utility packed with methods for everyday calculations.

Let's explore the essentials:

πŸ”ΈMath.random() – Generates a random number between 0 (inclusive) and 1 (exclusive):

console.log(Math.random()); // 0.374... (changes each time)

Useful for random IDs, colors, or game logic.

πŸ”ΈMath.pow(x, y) – Raises x to the power of y:

console.log(Math.pow(2, 3)); // 8

We usually prefer the modern x**y syntax, but Math.pow still works everywhere.

πŸ”ΈMath.sqrt(x) – Returns the square root:

console.log(Math.sqrt(16)); // 4

πŸ”ΈMath.abs(x) – Gives the absolute (positive) value:

console.log(Math.abs(-42)); // 42

πŸ”ΈMath.sign(x) – Tells us if a number is positive (1), negative (-1), or zero (0):

console.log(Math.sign(-5)); // -1
console.log(Math.sign(5)); // +1
console.log(Math.sign(0)); // 0

πŸ”ΈMath.max() – Returns the largest of the numbers given, or -Infinity if there are no numbers given

console.log(Math.max(1, 3, 2)); // 3
console.log(Math.max()); // -Infinity

πŸ”ΈMath.min() – Returns the smallest of the numbers given, or Infinity if there are no numbers given

console.log(Math.min(1, 3, 2)); // 1
console.log(Math.min()); // Infinity

These are our bread-and-butter methods for standard calculations.

πŸ“ Rounding & Formatting Numbers

When dealing with real-world data, especially prices or measurements, rounding is key:

πŸ”ΈMath.round(x) – Rounds to the nearest integer:

console.log(Math.round(4.6)); // 5
console.log(Math.round(4.3)); // 4

πŸ”ΈMath.floor(x) – Always rounds down:

console.log(Math.floor(4.9)); // 4

πŸ”ΈMath.ceil(x) – Always rounds up:

console.log(Math.ceil(4.1)); // 5

For formatting numbers with fixed decimals:

πŸ”Έ.toFixed(n) – Rounds and returns a string with n decimal places:

let price = 19.987;
console.log(price.toFixed(2)); // "19.99"

⚠️ Gotcha: Returns a string β€” convert back with +price.toFixed(2) if you need a number.

πŸ”Έ.toPrecision(n) – Formats to a specified total number of significant digits:

let num = 123.456;
console.log(num.toPrecision(4)); // "123.5"

βš™οΈ Math Object Advanced Features

πŸ”ΈMath.trunc(x) – Removes decimal part without rounding:

console.log(Math.trunc(4.9)); // 4

πŸ”ΈMath.hypot(a, b) – Returns √(aΒ² + bΒ²):

console.log(Math.hypot(3, 4)); // 5

πŸ”ΈMath.clz32(x) – Counts leading zeros in a 32-bit binary representation:

console.log(Math.clz32(1)); // 31

πŸ”ΈMath.imul(a, b) – Performs 32-bit integer multiplication, often faster:

console.log(Math.imul(2, 4)); // 8

We've got plenty more Math goodies to play with β€” like Math.exp(), Math.log(), Math.sin(), etc β€” perfect for heavy-duty math and scientific wizardry πŸ§ͺ✨.

Want to explore the complete toolbox? Check out MDN's Math docs πŸ“š.

πŸ”’ BigInt: Beyond Safe Integers

Regular Javascript numbers are 64-bit floating-point, meaning they safely store integers only up to:

console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991

Beyond that, precision breaks and weird things happen:

console.log(9007199254740991 + 1); // 9007199254740992 βœ…
console.log(9007199254740991 + 2); // 9007199254740992 ❌ (wrong!)
console.log(9007199254740992 === 9007199254740993); // true 😱 β€” precision lost!

Enter BigInt (ES2020)

To solve this, BigInt was introduced in ES2020. It's a new primitive type for arbitrary-size integers without losing precision.

You create a BigInt by adding an n to the end of an integer, or using the BigInt() constructor:

const bigNumber = 1234567890123456789012345678901234567890n;
console.log(bigNumber); // 1234567890123456789012345678901234567890n

const anotherBig = BigInt("987654321098765432109876543210");
console.log(anotherBig);

Gotchas:

You can't mix BigInt and regular Number types directly:

console.log(10n + 5); // TypeError: Cannot mix BigInt and other types ❌

Use the BigInt() constructor to convert:

console.log(10n + BigInt(5)); // 15n βœ…

Alternatively, end regular numbers with 'n' to convert them to BigInt.

const big = 123456789012345678901234567890n;
console.log(big + 2n); // 123456789012345678901234567892n

When to use it?

  • Cryptography

  • Financial apps

  • Scientific computing

  • Anything that needs integers beyond safe limits.

⏱️ Working with Dates & Numbers

The Date object is Javascript's built‑in tool for dealing with time and dates.

Dates in Javascript are just numbers under the hood β€” specifically, the number of milliseconds since January 1, 1970, UTC (the Unix epoch). Every time we call Date.now(), Javascript hands us that number:

console.log(Date.now());  // Example: 1731907591000 (milliseconds since 1970-01-01 UTC)

This "timestamp" is super helpful when we need to:

  • Measure time (like checking how long a task took).

  • Store dates in databases (timestamps are language-agnostic).

  • Do date arithmetic (add/subtract time in ms).

We often use timestamps for measuring performance:

let start = Date.now();
// Some operation
let elapsed = Date.now() - start;

console.log(`Time taken: ${elapsed}ms`);

We can also convert a Date object to a number using the unary plus (+) operator:

let now = new Date();
console.log(+now); // Same as Date.now()

Why does this matter?

  • Precision: Using timestamps avoids issues with different time zones and string parsing.

  • Math-friendly: We can easily add or subtract to get future or past times. For example, let's set an expiry time for 10 minutes from now:

let expiry = Date.now() + 10  60  1000; // 10 minutes in ms
console.log(expiry);

⚠️ Gotcha: Remember, timestamps are in milliseconds, so if you're comparing against APIs that use seconds (like many backends), you'll need to divide or multiply by 1000.

Here are the essentials we'll use most often:

Creating Dates

Current date and time:

let now = new Date();
console.log(now); // e.g., Fri Jul 18 2025 10:23:45 GMT+0000

From timestamp (milliseconds since epoch):

let fromTimestamp = new Date(1731907591000);

Specific date and time:

let birthday = new Date(1995, 6, 18, 12, 30); // months are 0-indexed!

Getting Date Components

The Date object has methods to get specific parts of the date:

let today = new Date();

console.log(today.getFullYear()); // 2025
console.log(today.getMonth()); // 0–11 (0 = January)
console.log(today.getDate()); // Day of the month (1–31)
console.log(today.getDay()); // Day of the week (0 = Sunday)
console.log(today.getHours()); // Hours (0–23)
console.log(today.getMinutes()); // Minutes
console.log(today.getSeconds()); // Seconds

⚠️ Gotcha: Months are zero-indexed β€” January is 0, December is 11.

Setting Date Components

We can modify existing dates with setFullYear(), setMonth(), setDate(), etc.:

today.setFullYear(2030);
today.setMonth(0); // January

Timestamps

Current timestamp:

console.log(Date.now()); // milliseconds since 1970-01-01 UTC

Convert a Date to a timestamp:

console.log(+today); // same as Date.now() for "today"

Date Arithmetic

Since dates are just timestamps, adding or subtracting time is easy:

let tenMinutesLater = Date.now() + 10 * 60 * 1000; 
// 10min * 60sec * 1000msec gives 10 minutes in milliseconds.

Formatting Dates

toISOString(), toDateString(), toLocaleString(), etc., help convert dates into readable formats:

console.log(today.toISOString()); // "2025-07-18T10:23:45.000Z"
console.log(today.toLocaleString()); // Localized format

Real-world use cases:

  • Tracking when a user last logged in.

  • Measuring API response times.

  • Creating countdown timers and stopwatches.

You can find more on Date objects at MDN ✨

πŸš€ Performance Optimisations

  • Avoid unnecessary type conversions (e.g., converting numbers to strings and back).

  • Use integers where possible β€” they're faster to process.

  • Minimise operations inside loops.

  • Cache computed values instead of recalculating repeatedly.

Wrapping Up

Javascript numbers go far beyond simple arithmetic. We now know how to:

  • Use the Math object for calculations, rounding, and formatting.

  • Handle huge integers with BigInt.

  • Work with timestamps

  • Avoid floating-point pitfalls in money.

  • Squeeze performance with careful numeric operations.

There's still a whole den of advanced topics β€” bitwise operations (&, |, ^, <<, >>>), IEEE 754 internals, and WebAssembly-level optimisations β€” but what we've covered is more than enough for our current journey.

For deeper dives:

Stay tuned and keep your code clean! πŸš€

0
Subscribe to my newsletter

Read articles from Sangy K directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sangy K
Sangy K

An Introvert Coder | Trying to be a Full-stack Developer | A Wannabe Content Creator