Chances are, growing up, you ran into at least one person who prided him/herself on being able to recite the value of Pi to the bazillionth digit:
Maybe you knew this kid:
Anyway, for most real-world situations, you don't need to go into a whole lot of detail. Something less precise for Pi...such as the most I can remember will do just fine:
In this tutorial, you will learn how to do that.
Why Round Numbers?
You may be wondering why anybody would want to go from having values that are more precise to having values that are less precise. In this section, I'll provide some examples.
Displaying on the Pixel
In general, whatever you are displaying on screen looks best when it is position and size values fall on a whole pixel. If you are using fractional values, what you are displaying may end up looking blurry:
[ notice how the text gets blurrier as we go off-pixel ]
When you are using code to move things around the screen, if you are not careful, your values may start to show various levels of unnecessary precision. An easy way to ensure everything falls on pixel boundaries is to round any position or size value to a whole number.
For performance intensive tasks, working with round numbers is faster than having to deal with numbers that contain extra precision. Though, this is less of an issue nowadays than it was before.
- var blah = .1 * .2;
What do you think will get written?
If you thought that what gets written is .02, you would be wrong. Here is what actually shows up:
[ not what you were expecting, right? ]
The reason for the odd appearance of the 4 has to do with how fractions are represented as floating point values. It is weird, but that's just how it is. By rounding your number, you can account for that unnecessary precision and just get .02.
Rounding the Number
Rounding to the Nearest Integer
The most common function for rounding your value is the prom king himself, Math.round:
- Math.round(1.532) // 2
- Math.round(1.235) // 1
- Math.round(27.94) // 28
- Math.round(.0005) // 0
This function works by rounding your number to the nearest integer. If the first number after the decimal is 5 or higher, it rounds up. If the first number after the decimal is 4 or lower, it rounds down. The Math.round function most closely resembles what you may have learned in school.
Its equally popular variants are the Math.floor and Math.ceil functions. Whereas Math.round would either round up or down depending on what the number after the decimal is, Math.floor will always round down to the next lowest integer regardless of what the value after the decimal is. Similarly...in an opposite way, Math.ceil will always round up to the next highest integer regardless of what the value after the decimal actually is:
- Math.ceil(1.5) // 2
- Math.floor(1.5) // 1
- Math.floor(1.235) // 1
- Math.ceil(.0005) // 1
All of this should look pretty straightforward. Just to drive the point home about the next highest and lowest integers, let's look what happens when we are dealing with negative values:
- Math.ceil(-45) // -45
- Math.floor(-45) // -45
- Math.ceil(-.5) // 0
- Math.floor(-.5) // -1
- Math.round(-45) // -45
- Math.round(-.5) // -1
- Math.round(-1.24) // -1
The Math.ceil and Math.floor functions work as expected. They round up or down to the next largest or smallest integer. Remember, in the negative world, the smaller the absolute value of your number, the larger its actual value:
That is why rounding up from -.5 results in you getting 0. If you think of the relative size of numbers as being on the number line, Math.ceil goes right. Math.floor goes left. It's like opposite day over there.
Our prom king Math.round, though, exhibits some slightly shallow behavior. Instead of rounding up or down to the nearest large or small number, this function literally rounds up or rounds down based on the absolute value of the number. That is why rounding -.5 is actually a -1 (a smaller number) than being 0 like you may expect.
Rounding to Arbitrary Levels of Precision
In the previous section, you learned how you can round to the nearest integer. There will be times when you want to round to a particular decimal position for extra preciseness.
Let's say I want to round our value of Pi to just 2 digits past the decimal point. In other words, I want 3.14159 to be rounded off to 3.14. Using the three amigos (Math.round, Math.floor, and Math.ceil) without any modification will cause my value to either be 3 or 4. I don't want that.
Let's look at our specific example first. To get two decimal positions of precision, multiply your number by 10 to the power of two (aka 100) and round that value:
- Math.round(3.14159 * 100);
That's not all you have to do. Divide the result of this rounding operation by 10 to the power of two again to get the answer you are looking for:
- Math.round(3.14159 * 100) / 100; // result is 3.14
To generalize this a bit, here is a basic formula:
The d stands for the number of places after the decimal point you want to go to. The number is the value you are trying to round. Everything else should be self-explanatory.
Using this model, here is how I would round 3.14159 to the tenths, hundredths, thousandths, and ten thousandths positions:
- Math.round(3.14159 * 10) / 10; // 3.1
- Math.round(3.14159 * 100) / 100; // 3.14
- Math.round(3.14159 * 1000) / 1000; // 3.142
- Math.round(3.14159 * 10000) / 10000; // 3.1416
You can substitute Math.round with Math.floor or Math.ceil depending on what exactly you are going for, and the behavior will be predictable.
Normally, I would have something witty to say here. Actually, who am I kidding? My conclusions are usually pretty awful. In fact, nobody even reads this section. I could write whatever I want and nobody would notice. Besides, what is there to conclude about rounding numbers?
If you have questions, need some assistance on this topic, or just want to chat - please drop by our friendly forums and post your question. There are a lot of knowledgeable and witty people who would be happy to help you out. Plus, we have a large collection of smileys you can use
Did you enjoy reading this and found it useful? If so, please share it with your friends:
If you didn't like it, I always like to hear how I can do better next time. Please feel free to contact me directly at kirupa[at]kirupa.com.