Numbers and Math

One very important part of JavaScript is mathematics, which is used a lot when it comes to controlling what happens in the script. If you do not like math, maybe scripting is not for you.

Basic Mathematics

One of the most important things in JavaScript is math, which almost every programming language in the world relies on. Sometimes a variable with a numerical value isn't arbitrarily changed, but has its value adjusted to reflect some new criteria. This is critical when the same set of instructions are run over and over again in a loop, which I'll get to later.

If you wanted to assign the value of 5 to foo, you could simply write foo = 5;. If you wanted to assign the value of 3 to foo, you would simply type foo = 3;. If you wanted to assign the value of 3/5 to foo, you could type foo = 0.6 (which is 3/5 in decimal notation). But what if you wanted to assign the value of 5/3? The value isn't exactly 1.667; the 6 after the decimal repeats infinitely, and 1.667 is simply rounding the value to the nearest thousandth. To get the exact value, you would have to write the equivalent of The variable foo contains the value of 5 divided by 3, which is written:

foo Is Equal To 5 / 3
foo = 5 / 3;

Math Operators

There are several operators in JavaScript, most of which are familiar, some of which may not be.

+
This adds two numbers together. Example: 5 + 3 = 8
-
This subtracts the second number from the first. Example: 5 - 3 = 2
*
Multiply. As there is no way to write the usual times symbol (×) in JavaScript and x is a letter, we use * instead. Example: 5 * 3 = 15
/
Divided by. As there is no way to write ÷ in Javascript (it even requires a special character in (X)HTML), / is used instead. Example: 5 / 3 = 1.666666...
%
This is the modulus operator, and it gives the remainder of a division. It's best if you use this solely with integers. Throw decimals into the mix, and answers may get mighty strange. Example: 5 % 3 = 2

Math With Variables

Doing math with variables rather than plain numbers isn't much more difficult. All the above applies.

For example, if you were calculating the decimal value of fractions, and both numerator and denominator were in variables:

The Numerator Is 5; The Denominator Is 3
var num = 5; // The numerator of the fraction
var den = 3; // The denominator of the fraction
var foo = num / den; // Calculating the actual fraction.

While this may seem the same as writing var foo = 5 / 3, it does allow you to use the variables num and den several times. And, should you desire to change them, you need change the values only once, where they were originally set.

Adjusting A Variable's Value

Just as you can adjust a string contained in a variable, you can also adjust numbers. For example, the following code means the new value of foo is the old value of foo minus 1.

Lowering The Value Of foo By 1
foo = foo - 1;

Might I point out right now, this depends on foo already having a numerical value. If the variable you're using doesn't have a numerical value yet, the browser will get confused, and you will get errors, since you are literally asking it     - 1 = ? (note the blank), leaving the browser with nothing to work with.

So let me demonstrate how this might be used:

Changing The Value Of foo
var foo = 5; // The variable foo is declared and has the value "5".
foo = foo - 1; // The value of foo has 1 subtracted from it, leaving foo with the value "4".
foo = 5 - foo; // The value of foo is subtracted from 5, leaving foo with the value "1".
foo = foo * 3; // The value of foo is multiplied by 3, leaving foo with the value "3".
foo = foo * foo; // The value of foo is multiplied by foo, leaving foo with the value "9".
Shorthand

Adjusting numbers is so common, there are actually several operators that act as shorthand means of doing so. These operators consist of one of the mathematical operators (+, -, /, *) followed immediately by the equal sign (no space between). However, in every case, the variable's value must come first in the equation for this kind of shorthand to work. I'll demonstrate with the above equations:

foo = foo - 1;
Shorthand equation: foo -= 1;
foo = 5 - foo;
foo comes second in this equation, so the shorthand method won't work.
foo = foo * 3;
Shorthand equation: foo *= 3;
foo = foo * foo;
Shorthand equation: foo *= foo;
Incrementing And Decrementing

It is extremely common to add or subtract 1 from a numerical variable—so common that these also have their own operators:

Incrementing And Decrementing The Value Of foo
foo++; // The variable foo increased by one.
foo--; // The variable foo decreased by one.

More Complex Equations

Equations can (and do) get more complicated. For example, if several pencils are stacked so they form an equilateral triangle (and this can be done), there is an equation to determine how many there are in the stack. Let foo represent the number of pencils in the bottom row. Below is a step-by-step description of how to calculate that.

  1. Add 1 to foo
  2. Multiply the result by foo
  3. Divide that result by 2.

One might think that the code should read like this (let's set foo to 5):

The Equation
var foo = 5;
var answer = foo + 1 * foo / 2;
document.getElementById("JS").firstChild.data = answer;

Okay, first let's go through the steps:

  1. Add 1 to 5 (The answer is 6)
  2. Multiply the result by 5 (The answer is 30)
  3. Divide that result by 2. (The answer is 15)

If you physically stack the pencils in such a way and count them, you will see that the answer is indeed 15. So let's see the result of our script:

Mathematic mistake

Something has clearly gone wrong.

What you must understand is that certain operators take precedence over others: / and * are calculated first, then + and -. You might remember this from school, but a reminder never hurts.

Therefore, JavaScript will run the equation in this manner (what's being executed will be underlined):

The equation:
foo + 1 * foo / 2
foo equals 5.
5 + 1 * 5 / 2
Division and multiplication first:
5 + 1 * 5 / 2 = 5 + 2.5
Addition (and subtraction) last:
5 + 2.5 = 7.5

The way to override precedence is to use parentheses (( )). Javascript calculates what's inside parentheses first, then moves outside them. To get the right answer, we need to use them. I will show you how to adjust the equation using the steps I explained earlier:

The original equation:
foo + 1 * foo / 2
Step 1: Add 1 to foo
(foo + 1) * foo / 2
Step 2: Multiply the result by foo
Step 3: Divide that result by 2.
No change needs to be made to this equation.

Fixing the above code ( and setting foo to 5) gives me:

The Corrected Equation
var foo = 5;
var answer = (foo + 1) * foo / 2;
document.getElementById("JS").firstChild.data = answer;

The result:

Mathematics fixed

The right answer.

Mathematical Constants

Irrational numbers cannot be described by fractions or whole numbers. The more common ones are properties of the Math object, so they must be preceded by Math. These are:

Below is a script that assigns these constants to a series of dd elements.

Assigning Constants To dd Elements
var dds = document.getElementsByTagName('dd');
dds[0].firstChild.data = Math.E;
dds[1].firstChild.data = Math.PI;
dds[2].firstChild.data = Math.SQRT2;
dds[3].firstChild.data = Math.SQRT1_2;

And the result

Constants of the Math property

Note that these are numbers, not strings. So of you wanted to get the fourth through eighth decimal spaces of the result of dividing the circumference of a circle by its diameter, you would have to convert the constant to a string, then run the appropriate method on it:

Getting The Desired Decimal Points
// The first decimal point is at 2, so the fourth would be at 5 and the eighth at 9.
Math.PI.toString().slice(5,9);

And there you have it: a slice of π. Yes, I did all that just for the pun of it. :-)

Mathematical Procedures

There are several procedures associated with mathematics which are difficult to replicate using multiplication, division, addition and subtraction. Two are standalone functions, the rest are methods associated with the Math object.

I mentioned earlier that you can place a variable in a procedure call. Entire equations will work as well, and since they're in parentheses (this time the parentheses of the procedure call) they'll be executed before the procedure is called.

Standalone Functions

Number(x)
This function will convert the string contained in x into an actual number. However, if a string :
  • has any characters besides numbers (0-9), decimal points (.) or negative signs (-),
  • has more than one decimal,
  • has more than one negative sign,
  • or has a negative sign anywhere else than at the very beginning of the number,
this method will return the message NaN, which means Not a Number.
isNaN(x)
This function returns a simple boolean value, saying whether a string can be converted into a number (whereupon it returns false) or not (whereupon it returns true). It means is Not a Number.

So why would you want to convert a number into a number? Well, notice that the concatenation operator that I mentioned in Text and the addition operator is one and the same: +. Does this have an effect? Well, let's take the following p element, containing two numbers to be added together. Each number is stored in a span element for retrieval by the script.

A Paragraph With Two Numbers To Be Added
<p><span id="num_1">5</span> + <span id="num_2">6</span> = <span id="sum">&nbsp;</span></p>

So let's retrieve the numbers and add them together:

Adding(?) Two Numbers Together
var num_1 = document.getElementById('num_1').firstChild.data;
var num_2 = document.getElementById('num_2').firstChild.data;
document.getElementById('sum').firstChild.data = num_1 + num_2;
What a surprise

What happened here is whenever JavaScript gets anything from the data property, it assumes that that is text, therefore it should be concatenated. Thus, to add these two numbers together, they must be converted to a number.

Adding Two Numbers Together
var num_1 = Number(document.getElementById('num_1').firstChild.data);
var num_2 = Number(document.getElementById('num_2').firstChild.data);
document.getElementById('sum').firstChild.data = num_1 + num_2;
What a surprise

Math Methods

Math.random()
Returns a random number higher than 0 and lower than 1. To get a random integer, multiply the generated random number by the highest number you want, and nest that equation in either ceil, floor or round, which will round it to an integer.
Math.max(x, y)
Returns the higher value
Math.min(x, y)
Returns the lower value
Math.pow(x, y)
This will return x raised to the power of y. For example, if x = 10 and y = 2, the above method would return 102, or 100. This can also be used to return roots, such as square roots or cubic roots, with a slight adjustment to the equation. To use this to get the square root of 100, you would enter Math.pow(x, (1 / y)) where x = 100 and y = 2. Because of the way exponents work, 100½ is equal to √100 (which, of course, equals 10). By the way, you don't need to stick with integers for this. The square root of 2 to the power of E/π is around 1.3497. Yes, that's in the examples.
Math.sqrt(x)
This also gets the square root of x. However, there is no special method of getting the cubic root of a number, so the fraction trick I showed you with pow still applies.

Rounding Methods

These methods round to the nearest integer, but how they do it is slightly different for each. All methods are part of the Math object.

Math.round(x)
This will round a number to the nearest integer.
Math.ceil(x)
Short for ceiling. This will round x up to the nearest integer. So if x is equal to 0.0000000001, ceil will round it up to 1.
Math.floor(x)
This will round x down to the nearest integer. So if x is equal to 0.9999999999, floor will round it down to 0.

Examples of each are below:

round
Rounding a number to the nearest integer or multiple of 10
ceil
Rounding a number UP to the nearest integer.
floor
Rounding a number DOWN to the nearest integer
Rounding to Something Else

Always remember that these methods round to the nearest integer. To round to the nearest ten tenth, five, or twenty, you need to do a little mathematical acrobatics. First, decide what number you want to round by (let's say to the nearest tenth). Divide the number you want to round by 0.1 (which is the same as multiplying by 10), use your desired rounding method, then multiply by 0.1. There, you've rounded to the nearest tenth. If you want to round to the nearest 10, you have to perform the same steps, except using the number 10 instead of 0.1.

Nearest Tenth, Five Tenths (Half), Five, Ten, and Twenty
x = Math.round(x / 0.1) * 0.1 // Nearest tenth
x = Math.round(x / 0.5) * 0.5 // Nearest five tenths (half)
x = Math.round(x / 5) * 5 // Nearest five
x = Math.round(x / 10) * 10 // Nearest ten
x = Math.round(x / 20) * 20 // Nearest twenty

Below I've created a page that rounds a number to the above values, using this type of equation. The script is a bit different, but only so it can retrieve values from and write other values to the table.

Rounding a number to the above values
A Demonstration Of Such Rounding
var trs = document.getElementsByTagName('tr');
// 14.27
var tds1 = trs[2].getElementsByTagName('td');
var num1 = Number(tds1[0].firstChild.data);
tds1[1].firstChild.data = Math.round(num1 / 0.1) * 0.1;
tds1[2].firstChild.data = Math.round(num1 / 0.5) * 0.5;
tds1[3].firstChild.data = Math.round(num1 / 5) * 5;
tds1[4].firstChild.data = Math.round(num1 / 10) * 10;
tds1[5].firstChild.data = Math.round(num1 / 20) * 20;
// 6.73
var tds2 = trs[3].getElementsByTagName('td');
var num2 = Number(tds2[0].firstChild.data);
tds2[1].firstChild.data = Math.round(num2 / 0.1) * 0.1;
tds2[2].firstChild.data = Math.round(num2 / 0.5) * 0.5;
tds2[3].firstChild.data = Math.round(num2 / 5) * 5;
tds2[4].firstChild.data = Math.round(num2 / 10) * 10;
tds2[5].firstChild.data = Math.round(num2 / 20) * 20;
The toFixed Method

If you want to round a number to the nearest five or twenty, you have to use the division/multiplication method above, though. If, however, you want to round a number to the nearest multiple of 10 or 1/10, you can use the toFixed method.

The toFixed method works a bit differently than the above methods. It does round a number as does round, but in this case the number is rounded to a multiple of 10 and rather than returning a number (as round, floor and ceil do), toFixed returns a string; if you wanted to continue using the result as a number, you'd have to use the Number function to revert it. Another difference is that this method is used on the number (or variable containing that number) itself, rather than being used with the Math object.

Using toFixed
x.toFixed(y)

In the above example, x is the number you are rounding; y is the number of decimal places to which you are rounding x. If y is:

Omitted
Zero
x is rounded to the nearest integer.
A positive number
x is rounded to the number of decimal places stated in y.
A negative number
x is rounded to the multiple of ten stated in positive y. For example:
y=-1
x is rounded to nearest 10.
y=-2
x is rounded to nearest 100.
A decimal (for example, 1.2)
y is rounded down to the nearest integer, then the result is calculated as normal
Using toFixed
<dl>
<dt>Round <span>8.5</span> to nearest integer (<code>toFixed()</code>)</dt>
<dd>&nbsp;</dd>
<dt>Round <span>8.5</span> to nearest tenth (<code>toFixed(1)</code>)</dt>
<dd>&nbsp;</dd>
<dt>Round <span>8.5</span> to nearest hundredth (<code>toFixed(2)</code>)</dt>
<dd>&nbsp;</dd>
<dt>Round <span>8.5</span> to nearest ten (<code>toFixed(-1)</code>)</dt>
<dd>&nbsp;</dd>
</dl>
<script type="text/javascript">
var dts = document.getElementsByTagName("dt");
var dds = document.getElementsByTagName("dd");
dds[0].firstChild.data = Number(dts[0].getElementsByTagName("span")[0].firstChild.data).toFixed();
dds[1].firstChild.data = Number(dts[1].getElementsByTagName("span")[0].firstChild.data).toFixed(1);
dds[2].firstChild.data = Number(dts[2].getElementsByTagName("span")[0].firstChild.data).toFixed(2);
dds[3].firstChild.data = Number(dts[3].getElementsByTagName("span")[0].firstChild.data).toFixed(-1);
</script>
Rounding a number to a fixed decimal point

You may wonder why on earth I converted the values in the various span elements' data properties to numbers, then back to strings via toFixed. Simply put, the value of a data property is always a string, and toFixed works on numbers, not on strings. I checked.

Getting Around A JavaScript Glitch

Here's a Little Known Fact: what is 0.6 × 3? If you said 1.8, you're wrong; it's 1.7999999999999998, and I will prove it.

Calculating 0.6 × 3
alert(0.6 * 3)
Who are you going to believe?  Your math teacher or a computer language?

All too often, Little Known Fact is synonymous with nonsense. The real answer is 1.8, which raises the question of what's going on here. Well, here's a fact that is true: 0.6 × 3 is a decimal equation—that is, it uses Base 10, which is very common in the everyday world.

Modern computers do all their calculations in binary—that is, Base 2—and while Base 2 corresponds very neatly with octal (Base 8) and hexadecimal (Base 16) notation, it does not match up so well with decimal (Base 10), as you can see in the sample table shown in Tables and also in the comparison of decimal and hexadecimal systems in Special Characters. The reason Base 2 lines up nicely with Base 8 and 16 but not Base 10 starts with the fact that 8 = 2 × 2 × 2, 16 = 2 × 2 × 2 × 2, but 10 = 2 × 5. The rounding and calculating that a computer has to do to get around that stubbornly unbinary 5 is the cause of such strange results as 0.6 × 3 = 1.7999999999999998.

So far as I know, this only shows up when multiplying decimals, so there are a couple ways you can try to get around such problematical calculations.

Adjust the calculation to avoid multiplying decimals

((0.6 * 10) * 3) / 10

0.6 × 10 = 6; 6 × 3 = 18; 18 ÷ 10 = 1.8

Use rounding to adjust for the error (say, using the toFixed method)

Number((0.6 * 3).toFixed(1))

0.6 × 3 = 1.7999999999999998 (according to JavaScript), 1.7999999999999998.toFixed(1) returns the string 1.8, and Number converts that string back to a number.

A Little Trick

I'd like to end this chapter with a little trick: getting a random element from an array. Of course, we'll need to use random, we'll need it to have a range equal to the length of the array, and we'll need to round it to an integer. Remember, though, that an array will never have an element that corresponds to the number in length, but it will have an element #0. So we want to use floor for this.

Random Element Of An Array
array[Math.floor(Math.random() * array.length)];

Step-by-step, this works out to...

Math.random()
Get a random number between 0 and 1.
* array.length
Multiply it by the length of the array.
Math.floor(...)
Round the result down to the nearest integer.
array[...]
Get the array element with that integer as the index.

There are other methods and properties as well, but this should do for now. If you want to learn the other properties and methods, you can go to the W3Schools math object reference at http://www.w3schools.com/jsref/jsref_obj_math.asp.