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


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 callMath.random()
orMath.round()
.Date
,JSON
, andIntl
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! π
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