Course: JavaScript

Progress (0%)

# JavaScript Number Methods

Chapter 16 20 mins

Learning outcomes:

1. Rounding to given significant figures using `toPrecision()`
2. Rounding to given decimal places using `toFixed()`
3. Converting to scientific notation using `toExponential()`
4. Converting numbers to binary, octal and hexadecimal

## Introduction

All programming languages appreciate the significance of numbers in computing and likewise provide utilities to easily work with them. JavaScript is no way behind — the language comes packed with a ton of things to facilitate in working with numbers.

In this chapter, we'll explore some methods natively available to JavaScript numbers via the `Number` interface, which we discovered in the previous chapter, JavaScript Numbers — Basics.

Specifically, we'll go over the different ways to round numbers in JavaScript and then consider conversions to different numerical bases including binary, octal, and hexadecimal.

## Rounding to significant figures

The `toPrecision()` method of the `Number` interface rounds a number to a given significant figure precision.

Its syntax is pretty basic:

``number.toPrecision(precision)``

The `precision` argument specifies the number of significant figures to round the given number `number` to. The method then returns back a string holding `number` in its rounded form.

Note that `precision` must be between `1` and `100`. Giving a value out of this range would result in an error.

If `precision` is a non-numeric value, or a value with a non-zero fractional part, it is converted to the nearest integer. This makes sense because the argument can only be an integer — we can't have 0.5 significant figures in a number!

Shown below are a bunch of examples.

First, let's see how are integers rounded:

``58 .toPrecision(2)``
'58'
``58 .toPrecision(3)``
'58.0'
``124 .toPrecision(3)``
'124'
``124 .toPrecision(4)``
'124.0'

(Take note of the space after every number written above and the `toPrecision()` method. This is necessary, as detailed in the snippet below.)

In the first statement, calling `toPrecision()` on `58` has no effect since the number already has 2 significant figures. In the second statement, the function returns a string containing a number with `0` added after the decimal point, i.e. `58.0`, to act as the third significant digit.

A similar reasoning applies to `124`.

#### Why is there a space in `58 .toPrecision(2)`?

Notice the space between each number and `.toPrecision()` in the code above:

• `58 .toPrecision(2)`
• `58 .toPrecision(3)`
• `124 .toPrecision(3)`
• `124 .toPrecision(4)`

It is necessary. Why?

This ensures that the JavaScript interpreter doesn't parse the `.` as a decimal point.

Removing the space, such as in `58.toPrecision()`, would lead to a syntax error.

``console.log(58.toPrecision(2)); // No space before .toPrecision()``
Uncaught SyntaxError: Invalid or unexpected token

This is because with the space removed, the parser thinks that the `.` is a decimal point, specifying the previous number's fractional part, and so would be followed by numeric digits.

But since this doesn't happen, and the `.` is instead followed by the word `toPrecision`, the parser raises a syntax error.

Time for a very quick quiz:

What would `10 .toPrecision(4)` return?

• `10`
• `'10'`
• `10.00`
• `'10.00'`

Now let's work with a couple of floats:

``1.2386 .toPrecision(2)``
'1.2'
``1.2386 .toPrecision(3)``
'1.24'
``1.2386 .toPrecision(4)``
'1.239'

In the first statement, the number `1.2386` is rounded to 2 significant figures, i.e. to the first decimal place. This causes the number to be rounded down to `1.2`, and then obviously coerced into a string.

In the second statement, the same number is rounded to 3 significant figures, i.e. to the second decimal place. This rounds the number to `1.24`, then returning `'1.24'`.

A similar explanation applies to the last statement as well.

Moving on, in cases where `precision` is less than the number of digits already in the given number, the returned string is in scientific notation.

Consider the snippet below:

``58 .toPrecision(1)``
'6e+1'
``124 .toPrecision(1)``
'1e+2'
``124 .toPrecision(2)``
'1.2e+2'
``178 .toPrecision(2)``
'1.8e+2'
``17000 .toPrecision(1)``
'2e+4'
``17000 .toPrecision(2)``
'1.7e+4'
``17000 .toPrecision(3)``
'1.70e+4'
``17000 .toPrecision(4)``
'1.700e+4'
``17000 .toPrecision(5)``
'17000'

In the first statement, the number `58` has two digits in it while the argument to `toPrecision()` is `1`. Clearly, this argument is less than 2, hence the representation returned by `toPrecision()` is in scientific notation. `58` rounded to 1 s.f. (significant figure) is `60`, which is equivalent to `6e+1`.

A similar explanation applies to the rest of the given statements.

In the last statement, the number of digits in `17000` and the argument to the `toPrecision()` method are both equal to one another, i.e. 5, so there is no conversion to scientific notation in the returned stringified number.

Stating it again, scientific notation is only used when the `precision` argument to `toPrecision()` is less than the number of digits displayed for the given number.

Now as you might agree, in cases where the resulting number (after this rounding) could otherwise be easily represented in normal decimal notation, this conversion to scientific notation could seem way too much.

Is there any way to solve it?

Hmm. Well, there is NO way to do so natively in JavaScript. But we could create our own function to solve this problem.

In the upcoming exercise, JavaScript Numbers — Better Precision, we'll get you to create such a function, processing the return value of `toPrecision()`.

Anyways, moving on, sometimes instead of wanting to round a number to given significant figures, it's desired to round it to given decimal places. This can be accomplished using the `toFixed()` method.

## Rounding to decimal places

The `toFixed()` method rounds a number to a given number of decimal places. And it also returns back the result in the format of a string (akin to `toPrecision()`).

The `toFixed()` method is commonly used in applications dealing with billing, currency, and financial statistics. Currency is typically represented with precision of 2 decimal places, i.e \$0.00, \$2.25, \$100.07, etc.

Following is the syntax of `toFixed()`:

``number.toFixed([digits])``

`digits` is the number of digits to place after the decimal point in the returned stringified number. By default, `digits` is set to `0`.

Remember that `[]` in the syntax snippet above doesn't represent an array but rather an optional parameter of a function.

Here's a demonstration of `toFixed()` on a couple of numbers:

``1 .toFixed()``
'1'
``1 .toFixed(0)``
'1'
``1 .toFixed(1)``
'1.0'
``1 .toFixed(2)``
'1.00'
``1 .toFixed(5)``
'1.00000'
``1.1286.toFixed()``
'1'
``1.1286.toFixed(0)``
'1'
``1.1286.toFixed(1)``
'1.1'
``1.1286.toFixed(2)``
'1.13'
``1.1286.toFixed(3)``
'1.129'

Time for a quick quiz again:

What would `-7.14165 .toFixed(3)` return?

• `-7.141`
• `'-7.141'`
• `-7.142`
• `'-7.142'`

Let's now consider a practical example using `toFixed()`.

In the code below, we log our total bill in an imaginative shopping app, by multiplying the price of an item (`price`) with its total quantity (`qty`):

``````var price = 3; // Price in \$
var qty = 10;

console.log('Your total bill is: \$' + (price * qty).toFixed(2));``````

Simple isn't it.

If you're thinking as to why is this method called 'toFixed', curious about the meaning of 'fixed' in there, the next snippet is for you.

#### Why is `toFixed()` called 'toFixed'?

The naming of an identifier shall always be the first step in understanding what it's meant for. Let's see where does the name 'toFixed' come from.

In programming, as we already know by now, we have floating-point numbers, where the decimal point literally 'floats' — it's not fixed at a given position. Unlike this, in fixed-point numbers, the decimal point is 'fixed', and always followed by the same number of digits.

Coming back to `toFixed()`, it converts a given number into a notation resembling that of a fixed-point number and that's exactly why we call it 'toFixed'.

Simple.

## Converting to scientific notation

To convert any number into scientific notation, we use the `toExponential()` method.

The `toExponential()` method takes in an argument and returns back a string holding its equivalent value in scientific notation.

Here's the syntax:

``number.toExponential([fractionDigits])``

`fractionDigits` gives the number of digits to put after the decimal point in the final scientific notation. If omitted, the number is converted to the most appropriate scientific notation.

Let's see some quick examples:

``152 .toExponential(0)``
'2e+2'
``152 .toExponential(1)``
'1.5e+2'
``152 .toExponential(2)``
'1.52e+2'
``152 .toExponential()``
'1.52e+2'

Shown below are even more examples, this time using actual floating-point numbers:

``243.74.toExponential(0)``
'2e+2'
``243.74.toExponential(1)``
'2.4e+2'
``243.74.toExponential(2)``
'2.44e+2'
``243.74.toExponential(3)``
'2.437e+2'

If you carefully notice, when the argument to `toFixed()` is less than the number of digits in the underlying number, its return value is the same as calling `toExponential()` with the same argument.

In other words, `toFixed()` internally either does some processing of its own or just calls `toExponential()`.

## Converting numbers to different bases

A highly useful method of numbers in JavaScript, but one that perhaps isn't cheered that much, is the `toString()` method.

Although `toString()` merely converts a number into a string when called with no arguments, if it is provided with an argument, it converts the number into the given base n representation.

``number.toString([radix])``

If provided, the argument has to be a number, specifying the radix of the converted number.

A number's radix, more commonly known as its base, specifies the numeric system on which the number is based.

Some common bases are base 2, known as binary; base 8, known as octal; and base 16, known as hexadecimal. The number system we use has the base 10, and commonly referred to as the decimal number system.

To illustrate this, following we convert the decimal number 15 into each of the following three representations: binary, octal, and hexadecimal:

``````var num = 15;

// Conversion to binary
var binNum = num.toString(2); // '1111'

// Conversion to octal
var octNum = num.toString(8); // '17'

var hexNum = num.toString(16); // 'f'``````
In hexadecimal, `f` stands for the number 15.
Since we can't have the bases 0 or 1 to represent numbers, calling `toString(0)` or `toString(1)` will throw errors.

These three conversions are by far the most common out there, but you can still experiment with other bases. See what each one returns!

And once again, note that this method also converts the number into a string; in effect, that is the sole purpose of `toString()`.

Therefore, before we can work with the converted number (which is a string), we ought to parse it into a number using `parseInt()` and the respective base of the number.

Following we have a task for you to exercise this number conversion logic.

Convert the binary string `'10110'` into hexadecimal representation (as a string), and save the result in a variable `hexNum`.

The following code has been set up for you to start with:

``````var binNum = '10110';
var hexNum = // put the result here``````

Note that the final result should be a string.

First we'll need to parse `binNum` into a number before we can convert this number into a hexadecimal number string.

To parse `binNum`, we'll use `parseInt(binNum, 2)`. Then, to convert its output into hexadecimal, we'll use `toString(16)`.

Combining both these functions, we have the following code:

``````var binNum = '10110';
var hexNum = parseInt(binNum, 2).toString(16); // '16'``````

`hexNum` turns out to be `'16'` which represents the decimal number 22. This is correct — the binary string `'10110'` also represents 22 in decimal format.

"I created Codeguage to save you from falling into the same learning conundrums that I fell into."

— Bilal Adnan, Founder of Codeguage