const - JS | lectureNumbers, Dates, Intl & Timers

Math and Rounding

Numbers, Dates, Intl & Timers

In this lecture, we will learn about some more mathematical operations and also about rounding numbers. We have already been using many mathematical operations, for example, plus, minus, times, divided, exponentiation, etc. And so we don't need to go over these again. So let's start here with the square root.

// Just like many other functions, sqrt is part of the Math namespace.

Math.sqrt(25); // 5
Math.sqrt(9); // 3
Math.sqrt(4); // 2

The same result could be achieved by using the exponentiation operator.

console.log(25 ** (1 / 2)); // 5
console.log(9 ** (1 / 2)); // 3

// You can also get the cube root by using 1/3
console.log(8 ** (1 / 3)); // 2

Next up, let's get the maximum value of a couple of values.

console.log(Math.max(5, 18, 23, 11, 2)); // 23
console.log(Math.max(5, 18, '23', 11, 2)); // 23 ==> Does type coercion
console.log(Math.max(5, 18, '23px', 11, 2)); // NaN ==> Does not do parsing

Just as we have the Math.max function, we also have the Math.min function.

console.log(Math.min(5, 18, 23, 11, 2)); // 2

Besides a couple of methods, there are also constants on the Math object or on the Math namespace. For example, if we wanted to calculate the area of a circle, we would need the value of pi. So for that, we can use the Math.PI constant.

const radius = 10;
console.log(Math.PI); // 3.141592653589793
console.log(radius ** 2 * Math.PI); // 314.1592653589793

Another thing that's on the Math object is the random function that we already have been using a couple of times. And it's very important to generate good random numbers when we need them.Remember we already used the Math.random function to create random dice rolls?

First, Math.random() will return a random number between 0 and 1.

console.log(Math.random()); // 0.123456789

Then we multiply that number by 6 since we want random numbers between 1 and 6 , and remove the decimal part using the Math.trunc function.

console.log(Math.trunc(Math.random() * 6)); // 4

But now, the problem is that we are getting numbers between 0 and 5 , and we want numbers between 1 and 6 . So we can add 1 to the result.

console.log(Math.trunc(Math.random() * 6) + 1); // 5

Let's now actually actually generalize this and create a function that will return a random integer between two values.

const randomInt = (min, max) => // do something..

As always, we need to start by removing any decimal part of the result of Math.random().

const randomInt = (min, max) => Math.trunc(Math.random());

We now need to multiply the result by the difference between the maximum and the minimum value, plus one.

const randomInt = (min, max) => Math.trunc(Math.random() * (max - min) + 1);

Before we move on, let me just quickly explain why we multiply by max - min. Math.random() will return a number between 0 and 1. So if we multiply that by max - min, we will get a number between 0 and max - min. And now, if we add min to that, we will get a number between min and max. So that's why we multiply by max - min.

// 1. Math.random() will return a number between 0 and 1
// 0...1

// 2. We multiply that by max - min
// 0...(max - min)

// 3. Add min to the result
// min...(max - min + min) = min...max

Let's now add the minimum value to the result.

const randomInt = (min, max) =>
  Math.trunc(Math.random() * (max - min) + 1) + min;

Let's test it out.

console.log(randomInt(10, 20)); // 15
console.log(randomInt(10, 20)); // 19
console.log(randomInt(10, 20)); // 13

Next, let's talk about rounding and let's start by rounding integers. We have already seen the Math.trunc function, which removes the decimal part of a number.

console.log(Math.trunc(23.3)); // 23
console.log(Math.trunc(23.9)); // 23

We also have the Math.round function, which rounds a number to the nearest integer.

console.log(Math.round(23.3)); // 23
console.log(Math.round(23.9)); // 24

Then we have the Math.ceil function, which rounds a number up to the nearest integer in Upward direction of rounding i.e towards the greater value.

console.log(Math.ceil(23.3)); // 24
console.log(Math.ceil(23.9)); // 24

And finally, we have the Math.floor function, which rounds a number down to the nearest integer in Downward direction of rounding i.e. towards the lesser value.

console.log(Math.floor(23.3)); // 23
console.log(Math.floor(23.9)); // 23

All these methods do type coercion, so they will also work with strings.

console.log(Math.trunc('23.3')); // 23
console.log(Math.round('23.9')); // 24
console.log(Math.ceil('23.3')); // 24
console.log(Math.floor('23.9')); // 23

Now you might think that floor and trunc are very similar. And indeed they do the same when we are dealing with positive numbers. So basically, floor and trunc both remove the decimal part when dealing with positive numbers. However, with negative numbers, they behave differently.

console.log(Math.floor(-23.3)); // -24
console.log(Math.trunc(-23.3)); // -23

Hence floor is a little bit better than trunc because it works in all situations, no matter if we are working with positive or negative numbers. We can therefore use floor instead of trunc in our randomInt function.

const randomInt = (min, max) =>
  Math.floor(Math.random() * (max - min) + 1) + min;

Let's now talk about rounding floating point numbers or decimals. Things work a little bit differently here. With floating point numbers, we have to specify the number in parenthsis, and then on that number we call the toFixed method.

One thing to note is that toFixed will always return a string and not a number.

// toFixed specifies the number of decimal places after the decimal point

console.log((2.7).toFixed(0)); // 3 ==> stringconsole.log((2.7).toFixed(3)); // 2.700 ==> string
console.log((2.345).toFixed(2)); // 2.35 ==> string
console.log(+(2.345).toFixed(2)); // 2.35 ==> number (Notice the + sign)

Just keep in mind that the above toFixed operations work similarly to the string methods. What I mean is, the 2.7 on the avove highlighted line is a number, and primitives actually don't have methods. Hence, behind the scenes, JavaScript will do boxing. And boxing is to basically convert the 2.7 to a number object, and then call the toFixed method on that number object. And then it will convert the number object back to a primitive once the operation is finished.

To finish, this lecture was just to give you a short overview of some more Math functions. And as always if there is anything you don't understand in this lecture or want to learn more you can always check out the MDN documentation.