Datatypes in-depth - Numbers

JavaScript, the language that breathes life into your web pages, is known for its dynamic and flexible nature. But this flexibility can sometimes be a double-edged sword, especially when it comes to dealing with numbers. Whether you’re calculating the bill for a street-side chai break or managing transactions in a large-scale financial application, understanding how JavaScript handles numbers is crucial. In this article, we'll take a deep dive into the Number data type in JavaScript.
JavaScript categorizes numbers into two types:
- Regular Numbers: These are 64-bit floating-point numbers, following the IEEE-754 standard. They are the most common and versatile, capable of representing both integers and floating-point numbers.
- BigInt: Introduced in ECMAScript 2020, BigInt allows for the representation of integers of arbitrary length. This is especially useful when dealing with very large numbers that exceed the safe integer limit of regular numbers.
In this article, we’ll focus primarily on regular numbers and explore how JavaScript manages these in various scenarios.
Let's understand with an example, shall we? - Calculating a Large Transaction
Let’s say you’re running a small business in Bangalore, selling refurbished laptops. A customer orders 1,000 laptops, each priced at ₹50,000. Your task is to calculate the total bill.
let pricePerLaptop = 50000;
let quantity = 1000;
let totalBill = pricePerLaptop * quantity;
console.log(totalBill); // 50000000
Here, the total bill is ₹50,000,000. JavaScript handles this calculation with ease, as the result is within the range of what a regular number can represent.
Making Numbers More Readable
When dealing with large numbers like ₹50,000,000, it’s easy to lose track of the number of zeroes. JavaScript allows you to use underscores (_
) to make such numbers more readable:
let totalBill = 50_000_000;
console.log(totalBill); // 50000000
This doesn’t affect the value of the number—it’s purely for readability.
Let's take another example:

Exponentiation
Another way to represent large numbers is through exponentiation. JavaScript lets you use the e
notation to simplify things. For example, instead of writing 1 billion as 1000000000
, you can write:
let billion = 1e9;
console.log(billion); // 1000000000
In our laptop business example, if the customer ordered 1 crore laptops (10 million), you could represent this as:
let quantity = 1e7;
let totalBill = pricePerLaptop * quantity;
console.log(totalBill); // 500000000000
Here, 1e7
represents 10 million, making the code cleaner and easier to understand.
Small Numbers and the e Notation
Just as e
can represent large numbers, it can also represent very small numbers. Imagine you’re calculating the cost per millisecond for running a server that costs ₹3.6 per second. Since 1 second equals 1,000 milliseconds, the cost per millisecond would be:
let costPerSecond = 3.6;
let costPerMillisecond = costPerSecond / 1e3;
console.log(costPerMillisecond); // 0.0036
Essentially the e
notation is very simple, you write a number, then write the character e
, and then the exponential, i.e the number of zeros to multiply it by, got it?
so to write thousand you can simply write 1 followed by 3 zeros right?
so guess how to write it using the e notation.
Did you guess it right?
The right answer would be: 1e3
Hexadecimal, Binary, and Octal Numbers
JavaScript also supports hexadecimal, binary, and octal number systems, which can be useful in various scenarios, such as color representation, bitwise operations, or working with memory addresses.
For instance, if you’re assigning a color to your website’s background, you might use a hexadecimal color code:
let color = 0xFF5733; // Hexadecimal representation of the color
console.log(color); // 16734003 (decimal equivalent)
Or, if you’re working with low-level operations, you might use binary or octal numbers:
let binaryNumber = 0b1010; // Binary representation of 10
let octalNumber = 0o12; // Octal representation of 10
console.log(binaryNumber); // 10
console.log(octalNumber); // 10
Converting Numbers to Different Bases
Hexadecimal, Binary, and Octal Numbers
We have covered how javascript deals with number systems in the Number systems article in detail, but here let's get into some practical aspects of the same.
JavaScript also supports hexadecimal, binary, and octal number systems, which can be useful in various scenarios, such as color representation, bitwise operations, or working with memory addresses.
For instance, if you’re assigning a color to your website’s background, you might use a hexadecimal color code:
let color = 0xFF5733; // Hexadecimal representation of the color
console.log(color); // 16734003 (decimal equivalent)
Or, if you’re working with low-level operations, you might use binary or octal numbers:
let binaryNumber = 0b1010; // Binary representation of 10
let octalNumber = 0o12; // Octal representation of 10
console.log(binaryNumber); // 10
console.log(octalNumber); // 10
Converting Numbers to Different Bases
We have understood how to manually do this in the Number systems article, here let's leverage Javascript to do it for us, shall we?
JavaScript allows you to convert numbers to different bases using the toString
method. This can be handy when you need to represent a number in a different numeral system:
let num = 255;
console.log(num.toString(16)); // "ff" (Hexadecimal)
console.log(num.toString(2)); // "11111111" (Binary)
In the context of our laptop business, if you wanted to create a short URL for an invoice ID, you could convert the ID to base 36:
let invoiceId = 123456;
console.log(invoiceId.toString(36)); // "2n9c"
Just an example to understand how we can leverage JS to simply things for us.
Rounding Numbers
Have you heard about floor and ceil? Imagine you are in a room, there is a floor and ceil, say the ceiling is number 1 and the floor is 0. Half the height of your room is how much?
Yes, 0.5 right?
Image it is a 10 foot tall room, so 5 foot would be 0.5, I hope you are able to imagine it.
Now, coming back to the topic of floor and ceil, floor will round up everything to the nearest number below. Say you are at 0.9, floor is o, but ceil does the opposite, for ceil, it is 1 - it rounds it up to 1.
Rounding numbers is a common operation in JavaScript, and the language provides several methods to do so:
Math.floor
: Rounds down to the nearest integer.Math.ceil
: Rounds up to the nearest integer.Math.round
: Rounds to the nearest integer, with ties rounding up.Math.trunc
: Removes the fractional part without rounding.

It is simple, right?
Imagine you’re calculating the average rating for your business based on customer reviews. If the average rating comes out to be 4.7, you might want to round it up to the nearest whole number:
let averageRating = 4.7;
let roundedRating = Math.round(averageRating);
console.log(roundedRating); // 5
Or, if you want to always round down:
let roundedRating = Math.floor(averageRating);
console.log(roundedRating); // 4
Dealing with Precision
One of the quirks of JavaScript is that it sometimes struggles with precise calculations due to the way it handles floating-point numbers. A common example is adding 0.1 and 0.2:
console.log(0.1 + 0.2); // 0.30000000000000004

This might seem like a bug, but it’s actually a result of how numbers are stored in memory. JavaScript uses binary floating-point representation, which can’t precisely represent some decimal fractions.
To avoid issues like this, especially in financial calculations, you can round the result to a fixed number of decimal places:
let sum = 0.1 + 0.2;
console.log(sum.toFixed(2)); // "0.30"
This ensures that the result is displayed as 0.30
instead of 0.30000000000000004
.

Handling Large Numbers with BigInt
If your laptop business expands and you start dealing with large financial transactions, you might encounter numbers that exceed the safe integer limit in JavaScript. This is where BigInt
comes in handy.
let largeNumber = BigInt(12345678901234567890);
console.log(largeNumber); // 12345678901234567890n
With BigInt
, you can safely handle numbers beyond the limits of regular numbers. However, keep in mind that BigInt
and regular numbers are not directly interoperable, so you’ll need to convert between them when necessary.
Infinity and NaN
JavaScript also has special numeric values like Infinity
and NaN
(Not-a-Number). These are useful in cases where calculations exceed the range of representable numbers or when operations don’t yield a valid number.
For example, dividing by zero results in Infinity
:
let result = 50 / 0;
console.log(result); // Infinity
On the other hand, operations that don’t produce a number result in NaN
:
let result = "laptop" / 2;
console.log(result); // NaN
You can check for these values using isFinite
and isNaN
:
console.log(isFinite(result)); // false
console.log(isNaN(result)); // true
Object.is for Strict Comparisons
JavaScript also provides Object.is
for strict comparisons, which is particularly useful when dealing with edge cases like NaN
and -0
.
console.log(Object.is(NaN, NaN)); // true
console.log(Object.is(0, -0)); // false
Numbers in JavaScript may seem simple at first glance, but as we’ve seen, they have many intricacies that can catch you off guard. Whether you’re calculating bills for a large order of refurbished laptops, managing financial transactions, or working with different numeral systems, understanding how JavaScript handles numbers is crucial.
With that let's move to the next Data structure, Strings!