Understanding toFixed and toPrecision number methods in Javascript

ยท

5 min read

Introduction

I was building a cart page recently where I have to show the total cost of all the products which includes tax and delivery charges and then I saw something like this...

image.png

And after seeing the value of tax I was like...

wait-what.gif

So the next thought was to convert the value to have 2 digits after the decimal, so I went to my dear friend Google (my rescuer ๐Ÿ˜‚) and typed limit number to 2 digits javascript or something like that and I found there are two methods that are built into javascript numbers that can help us with this problem, and our methods are ๐Ÿ‘‡

  • toFixed
  • toPrecision

But it was a little confusing initially about what is the differences between them and what to use in my scenario, I figured it after some time and I decided to blog so that my fellow mates don't face the same problem I faced, so let's dive into it

Number.prototype.toFixed()

Let's take an example

let num = 12345.6789
num.toFixed()

toFixed method takes 1 optional parameter digits which is the number of digits after the decimal point . of the resultant number, so if we pass 2 to toFixed method the resultant number will have two digits after the decimal. Let's look at some examples

let num = 12345.6789

// returns => "12346" : since we did not pass any argument to toFixed it assumes 
// 0 as the default value and hence it has 0 digits after the decimal
num.toFixed()       

// returns => "12345.7" : since we passed 1 we get one digit after the decimal 
// and  also note that the digits are round to nearest decimal number before 
// they are  removed from result
numObj.toFixed(1)      

// returns => "12345.678900": in the number 12345.6789 we only have 
// 4 digits after the decimal but since we passed 6 as the argument 
// it adds extra 2 zeros even though we don't have enough digits
numObj.toFixed(6)

This is how at the very basic level toFixed works, but this is not the end, as any other javascript concept toFixed also many use-cases and a few points to note, let's see some of them

  • toFixed returns a string
  • It does not return a exponential form (1.23e+20) unless the input is too large (largest is >= 1e+21)
  • Number is rounded to nearest decimal
    • 0 - 4 are rounded to 0
    • 5 - 9 are rounded to 0 and 1 is added to left digit
    • Examples: (1.24).toFixed(1) // 1.2, (1.25).toFixed(1) // 1.3, (1.26).toFixed(1) // 1.3

Some more examples

// returns => "123000000000000000000.00"
(1.23e+20).toFixed(2)  

// returns => "0.00"
(1.23e-10).toFixed(2)

Number.prototype.toPrecision()

To understand toPrecision we have to know what does it mean my significant figures because toPrecision which also takes one argument digits converts the given number to have digits number of significant figures, so it's important to understand what are significant figures

Understanding significant digits

There are some rules which help us to identify how many significant figures a number has, this can be a little confusing and it has a total of 8 rules to determine the number of significant figures in a given number, so we will go through a few basic ones but you can click here for more detailed information about all the rules

Significant figures rules
  1. All non-zero numbers are significant
    • 45.6 has three significant figures because all the digits are non zero
  2. Zeros between two non zero digits are significant
    • 2022 has four significant figures
  3. Leading zeros are not significant
    • 0.32 has only one significant figures
    • 0.00045 has only two significant figures
    • 0.040 has two significant figures
  4. Trailing zeros to the right of the decimal are significant
    • 78.00 has four significant figures
    • whereas 78 has only two significant figures

These should be enough to understand what toPrecision does so let's see some examples

let num = 5.123456

// returns => "5.123456" since nothing is passed it just returns the same number
num.toPrecision()

// Throws an RangeError => argument must be between 1 and 100
num.toPrecision(0)

// returns => "5"
num.toPrecision(1)

// returns => "5.1"
num.toPrecision(2)

// returns => "5.1235": note that if there are some digits to remove it does that 
// after rounding to nearest decimal
num.toPrecision(5)


let num2 = 0.000123

// returns => "0.000123" since nothing is passed it just returns the same number
num2.toPrecision()

// returns => "0.0001" : according to rule 2 of significant figures
num2.toPrecision(1)

// returns => "0.00012" : according to rule 2 of significant figures
num2.toPrecision(2)

// returns => "0.000123000": according to rule 3 of significant figures it adds
// extra digits at the end 
num.toPrecision(5)

If you are here, then pat yourself on back ๐Ÿฅณ, it's a lot.

Conclusion

I finally decided to use toFixed since 1 dollar has 100 cents it makes sense that I calculate my tax and just round it off to 2 digits ๐Ÿ‘‡

let productPrice = 40
let tax = 0.18

let taxPrice = productPrice * tax

let totalPrice =  (productPrice + taxPrice).toFixed(2)

console.log(totalPrice) // 45.20

I hope you found this article helpful. Thanks for reading ๐Ÿ™

Let's connect. I share my learnings on Life, Full-stack Javascript, Web Development

ย