Your Favorite Games


Beautifying Numbers

About this tutorial

Category: Javascript
Difficulty: Intermediate


Beautifying Numbers

A common aspect among incremental games is the concept of endlessly growing numbers. While the following snippets won't cover expanding over the number limit of Javascript, they will help you to display better looking numbers to your players, which is just as important!

Take a look at the following number:

  1. 570392175.23590

Can you tell exactly how large that number is? Millions? Billions? What about trailing decimal places? There are a couple of functions that we can apply here to make things look a bit better.

Javascript comes with a built in rounding function. It will round the number passed to it to the nearest whole number. This is incredibly useful, and can be used to provide us with as many decimal places as we might need. However, typing out the function every single time can be a little laborious, and if you're using it quite often, can increase the size of your program by precious bytes. The following function, while small, can handle all manner of rounding situations.

  1. function Round(input,forcedecimal) { //Round a number to the "forcedecimal" number of decimal places
  2. forcedecimal = Math.pow(10,forcedecimal); //Calculate the number of decimal places to round
  3. var result = Math.round(input * forcedecimal) / forcedecimal;
  4. return result;
  5. }

The function takes an input number and a number denoting how many decimal places should be saved. This number is then calculated as a power of 10 (10^1 = 10, 10^2 = 100, and so on). The multiplied number is then multiplied against our input, out input is rounded, then our rounded number is divided by the same multiplier we used in the beginning. The results?

Take the number 100.5544 and 2 decimal places. We get a forcedecimal value of 100 on the first line (10^2). Our number, 100.5544, is multiplied to 10055.44, rounded to 10055, then divided back to 100.55. Simple!

Now, what if we want to use larger numbers and add separators to them? The following function is a little more complex, but again, can be applied to any number of situations:

  1. function AddSeparators(input,separator,forcedecimal) { //Add separators to large numbers, returns a string
  2. var Before = String(input); //Turn the input into a string
  3. var SplitBefore = Before.split("."); //Split the input by "." to get the decimal
  4. var After = ""; //Reset the result
  5. var LastThree = ""; //Reset the last 3 characters
  6. while (SplitBefore[0].length > 0) { //While the left half of the number is still there
  7. LastThree = SplitBefore[0].slice(-3); //Take the last 3
  8. SplitBefore[0] = SplitBefore[0].slice(0,-3); //Remove the last 3
  9. if (After.length == 0) { After = LastThree; } else { After = LastThree + separator + After; } //Append the last 3
  10. }
  11. if (forcedecimal > 0) { //If the decimal number is enabled
  12. After += "."; //Add the decimal place
  13. var AddZeros = forcedecimal;
  14. if (SplitBefore[1]) { //If a decimal string already exists
  15. AddZeros -= SplitBefore[1].length; //Get the number of trailing zeros required
  16. if (AddZeros < 0) {AddZeros = 0;}
  17. After += SplitBefore[1].substring(0,forcedecimal - AddZeros); //Add the existing trailing digits
  18. }
  19. for (var zeros=0;zeros<AddZeros;zeros++) { //Add any trailing zeros
  20. After += "0";
  21. }
  22. }
  23. return After; //Return the number as a string
  24. }

It's a bit bigger isn't it? Let's first take a loot at what we pass to the function. An input number, a separator character (or string if you are so inclined), and how many decimal places to save. Remember that this function only beautifies and doesn't round, so you'll have to use your rounding function above if you want to round your numbers out.

First things first, lets transform that passed number into a string. This will allow us to tear it apart and reassemble it with the new separators in place. We'll then split our number into two strings, before the decimal and after the decimal. We'll then create a variable to hold our results and a string to help in parsing the number.

The while loop handles the front of the number. It records the last 3 characters of the string, removes them from our original split string, then adds them to the start of our output string, adding in the separator for any additions after the first. Note that the string is built backwards, allowing for the separators to be added in the right places.

The second half of the function is considerably more complex. First things first, we decide whether we want to add decimal places. If set to 0, we'll be passing none. If it's positive, however, we start by adding the decimal place and storing how many 0's we'll need to add. This number is only temporary though, and it'll change momentarily.

The if statement determines whether there is actually existing decimal places to add back in. If there's none, it will skip to the next function. If, however, there are decimal places (remember, these were stored in the second string from our split input), then it will decide just how many to add in, and how many zeros to add afterwards. We take the number of zeros we recorded before and subtract the length of our string (the number of digits there are). If our resulting number is below 0, we return it to 0 to prevent problems later.

We then add a section of the string back into the output. Remember how we returned our figure back to 0 before? This is why. We get a substring (a string from inside a string) starting at position 0 and continuing until position forcedecimal (the number of places we want) - AddZeros (the number of zeros we need to add at the end). Note here that if we didn't return to 0, our figure could be negative and ADDED back into the string, resulting in the whole string being output.

Finally, we create a loop to add the trailing zeros to the string. This figure could be 0, depending on the number that was passed and the number of decimal places that we want, and the function handles that just fine.

Remember, displaying numbers in a neat way to your players is critical to ensuring the come back to play your game again. The above 2 functions can easily handle this for you, and it's recommended that you do something at least similar. Long, hard to read numbers are a pain to work with, and will instantly turn away a lot of players.