Skip to content

Software Engineer at Polygon

Rounding and truncating numbers in JavaScript

Rounding and truncating is a bread and butter action for every single developer. It was covered during your first few math lessons in primary school. Hopefully you still remember how it works in the world of numbers.

5 or more? Raise the Score. 4 or less? Let it Rest.

Let’s use this knowledge and translate it to JavaScript using the built-in object called Math. As the name can suggests, it has a collection of properties and methods for mathematical operations on numbers. There is one small difference between Math and other built-in global objects. Math isn’t a constructor which means that all properties and methods that belong to it are static (meaning that they need to be called by using Math as an object).

Math Object in Google Chrome Console

Rounding vs Truncating #

The difference between these two methods is minor but very important to understand. Both of them are methods of approximating a number by dropping decimal places. Rounding approximates a number using a nearby number at a given degree of accuracy. It can occur in two directions: up and down. Rounding up approximates a number towards positive infinity. Rounding down towards negative infinity. Truncating approximates without rounding. In other words, it “rounds” towards zero.

Rounding
3.14159  3.1416

Truncating
3.14159  3.1415

Hopefully you get the difference. It makes truncating rarely useful in precise calculations (although JavaScript probably isn’t a good choice at all if you need precise calculations) but you can come across a situation when it may be irreplaceable. Once example can be when needing to drop decimal places from a pixel value to avoid anti aliasing or weird pixel rounding which is completely different across browser engines.

Rounding numbers in Javascript #

Rounding is straight forward. We can round to the nearest integer, round down or round up. JavaScript uses three methods to achieve this:

  • Math.round() - rounds to the nearest integer (if the fraction is 0.5 or greater - rounds up)
  • Math.floor() - rounds down
  • Math.ceil() - rounds up
Math.round(3.14159)  // 3
Math.round(3.5)      // 4
Math.floor(3.8)      // 3
Math.ceil(3.2)       // 4

Rounding numbers with decimal precision requires a little bit of calculation and Math.round(). Optionally we can use the toFixed() method that belongs to the Number prototype. The output type of toFixed() is a string which needs to be passed to a top-level function called parseFloat() to return a number. Unfortunately this seems to be really slow.

Math.round(3.14159 * 100) / 100  // 3.14

3.14159.toFixed(2);              // 3.14 returns a string
parseFloat(3.14159.toFixed(2));  // 3.14 returns a number

Truncating numbers in Javascript #

Math.trunc() simply removes all the fractional digits. It takes one argument which is a number. If the argument is a positive number it behaves exactly the same as Math.floor(). For negative numbers it does the same job as Math.ceil().

Math.trunc(3.14159);   //  3
Math.trunc(-3.14159);  // -3

It’s worth mentioning that the browser support for Math.trunc() isn’t great. It is part of new ES2015 (yeah, I prefer ES6 too) specification. Have a look at the browser support list:

  • Google Chrome >= 38
  • Firefox >= 25
  • Internet Explorer >= Nope :(
  • Opera >= 25
  • Safari >= 7.1

Luckily there is a way to use this without ES6 support (thanks to Johny who suggested this solution in comments below). We can use bitwise operators to accomplish this task. Unfortunately there are some restriction as well. All bitwise operations work on signed 32-bit integers. Using them converts a float to an integer. In practice it means that we can safely work up to 2^31−1 (2 147 483 647) which is much less than Number.MAX_VALUE (1.7976931348623157e+308). This isn’t a great idea for monetary calculations either.

3.14159 | 0;   //  3
-3.14159 | 0;  // -3

3000000000.1 | 0  // -1294967296 Ups :(

TLTR (too long to read) #

I know, I know - time is money. Lets sum it up.

  • Math.round() - rounds to the nearest integer
  • Math.floor() - rounds down towards negative infinity
  • Math.ceil() - rounds up towards positive infinity
  • Math.trunc() - rounds up or down towards zero (bad browsers support)

Math.floor() & Math.ceil() & Math.trunc() on timeline

Comments

  • N
    Nogamotyla

    Widely-supported way of truncating is bitwise operator:
    -3.99 | 0
    Although what's done here is not entirely clear. (bitwise shift operates on 32-bit numbers only so it returns those [integers])
    You can write your own truncating polyfill using just that.
    function truncate(number){ return number|0; }

    See which is faster for yourself here. :)
    http://jsperf.com/bitwise-v...

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Fantastic tip. I may update this article with your tip if you don't mind. I won't forget about kudos for Johny :) Thanks again, really nice hint!

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
      • N
        Nogamotyla

        No problem. :)

        👆 you can use Markdown here

        Your comment is awaiting moderation. Thanks!
        • Pawel Grzybek
          Pawel Grzybek

          Thanks a lot again. I just updated article and applied all your suggestions.

          https://github.com/pawelgrz...

          👆 you can use Markdown here

          Your comment is awaiting moderation. Thanks!
    • T
      Trina McLaren

      Your demo link is broken but my testing showed this |0 method to slightly faster than the rest (and the shortest to type). Math.trunc , Math.round etc are all about equal. toFixed(0) is exponentially slower (even before converting back to a number) and it also rounds kinda weird in some cases, like how (0.35).toFixed(1) = 0.3 yet (1.35).toFixed(1) = 1.4

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
      • Pawel Grzybek
        Pawel Grzybek

        I will fix the link. Thanks for pointing this one out and sharing your results!

        👆 you can use Markdown here

        Your comment is awaiting moderation. Thanks!
  • N
    Nogamotyla

    Another thing that came to my mind is that toFixed is returning a string, not a number. So to get the number you would have to use parseInt (slow), or another method of getting fixed numbers (fast):

    Math.round( 3.66666 * 100 ) / 100

    Check the speeds: http://jsperf.com/tofixed-p...

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Yeah I know what do you mean. I think you wanted to mention parseFloat() not parseInt() because in this example is all about floating points :-) Worth to add to article - definitely. Thank you so much for your input Johny. Can you give me your Twitter handle (if you have one). I'll update this article with all your advices later on today.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • e
    essay writing services review

    Rounding and truncating are really necessary for a developer to know and it's a good guide that you have created this article which can guide them on how to do it in Javascript.

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Thank you very much! I'm glad that you found it useful.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • G
    Gregory Krohne

    toFixed is unreliable for rounding. Try this:

    1.265.toFixed( 2 )
    parseFloat( 1.265.toFixed( 2 ) )

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • M
    Mauro Gabriel Titimoli

    // round to the nearest number taking into account the sign
    const round = number => Math.sign(number) * Math.round(Math.abs(number))

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • M
    Mauro Gabriel Titimoli

    // rounds a number to its closer taking into account sign
    const round = number => {
    if (number === 0) return 0;

    return number > 0
    ? Math.round(number)
    : Math.sign(number) * Math.round(Math.abs(number));
    }

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • D
    Devasish Panda

    That was a presentation!

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • G
    GO PI

    Hi I have a problem with JavaScript

    I have currency value 11.26 --I need always roundup ---12

    If I have 12.56 I need roundup 13.

    Thanks in advance.

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Hi.

      This is exactly what Math.ceil() is doing.

       
      Math.ceil(11.26);
      // 12

       
      Math.ceil(12.56);
      // 13

      Thanks

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
    • A
      Athinodoros Sgouromallis

      Someone didn't read a word of this post :P

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • B
    Brian

    The Math.round(3.14159 * 100) / 100 // 3.14 rounding approach will not always be accurate. There are a lot of situations where it will round down values:


    Math.round(0.145 * 100) / 100 // 0.14 not 0.15
    Math.round(1.005 * 100) / 100 //1 not 1.01

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • K
      Konstantin Benko


      Math.round(Math.round(0.145 * 1000) / 10) / 100 // 0.15
      Math.round(Math.round(1.005 * 1000) / 10) / 100 // 1.01

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • S
    Svani

    Hi,

    How can I change 9.26 to 9.27 using math.round ?

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      I am not sure if you understand the concept of rounding. It is not made for changing values but for rounding values.

      `9.26 + 0.01`

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
    • P
      Prasann Sitani

      Math.round rounds it to 9.
      If you want 9.27 then,
      You can do this by using parse float Method.
      Maybe:
      * parseFloat(9.264.toFixed(2)); //9.26
      * parseFloat(9.266.toFixed(2)); //9.27

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • A
    Amr Ali

    var truncated = number - number % 1;

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • A
    Amr Ali

    var rounded = number + 6755399441055744.0 - 6755399441055744.0; // 2^51 + 2^52
    This works for numbers with absolute value < 2 ^ 51.

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • P
    P Satish Patro

    var original=224.985
    document.getElementById("demo").innerHTML = Math.round(original*100)/100;
    var original2=224.98499999
    document.getElementById("demo2").innerHTML = Math.round(original2*100)/100;

    output
    224.99
    224.98

    in second case when no is 999999, it is not rounding to upper one
    What to be done to get second operation's value same as first one?

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • A
      Agyaey Tiwari

      https://t.co/sO86kEe3uX?Vqkugn

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
      • A
        Ahsan Ahmed

        https://t.co/yc6wKCq1xP?cjg...

        👆 you can use Markdown here

        Your comment is awaiting moderation. Thanks!
  • K
    Kalud

    Great article , thanks ! I wanted to ask though about this issue I encountered : somehow in Javascript : '28.99 - 28.70' is equal to => '0.28999999999999915' and not 0.29 ! How do I approach this to always get 0.29 ? 0.28999999999999915

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Hi Klaud.

      You just became a victim of the "floating-point arithmetic precision". For people, something as obvious may not be that obvious for computers because of how they deal with number. Google this term to find out more about it. A classic example!

      0.1 + 0.2 = 0.30000000000000004
      

      How to deal with it then? The answer isn't that simple, but it all comes down to avoid dealing with fractions if you can. In many e-commerce solutions, prices are represented like this…

      // Example for £15
      const price = {
        centAmmount: 1500,
        fractionDigits: 2,
        symbol: '£',
      }
      

      By operating with numeric values using notations like this, all operations are done on the centAmmount first, and then the final result is divided by the fractionDigits. Hopefully, that helps.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • M
    Mark Booster

    Nice This is and i have used this in my javascript code

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      I am glad it helped you out :)

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!

Leave a comment

👆 you can use Markdown here

Your comment is awaiting moderation. Thanks!