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.
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
, which is written:5 divided by 3
There are several operators in JavaScript, most of which are familiar, some of which may not be.
timessymbol (
×) in JavaScript and
xis a letter, we use
*instead. Example: 5 * 3 = 15
÷in Javascript (it even requires a special character in (X)HTML),
/is used instead. Example: 5 / 3 = 1.666666...
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:
var
num = 5; // The numerator of the fractionvar
den = 3; // The denominator of the fractionvar
foo = num / den; // Calculating the actual fraction.While this may seem the same as writing
, 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.var
foo = 5 / 3
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.
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:
var
foo = 5; // The variable foo is declared and has the value "5".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;
foo -= 1;
foo = 5 - foo;
foo = foo * 3;
foo *= 3;
foo = foo * foo;
foo *= foo;
It is extremely common to add or subtract 1
from a numerical variable—so common that these also have their own operators:
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.
One might think that the code should read like this (let's set foo to 5
):
var
foo = 5;var
answer = foo + 1 * foo / 2;document
.getElementById
("JS"
).firstChild
.data
= answer;Okay, first let's go through the steps:
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:
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 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:
Fixing the above code ( and setting foo to 5) gives me:
var
foo = 5;var
answer = (foo + 1) * foo / 2;document
.getElementById
("JS"
).firstChild
.data
= answer;The result:
The right answer.
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
. These are:Math
Below is a script that assigns these constants to a series of dd
elements.
dd
Elementsvar
dds = document
.getElementsByTagName
('dd'
);firstChild
.data
= Math
.E;
firstChild
.data
= Math
.PI;
firstChild
.data
= Math
.SQRT2;
firstChild
.data
= Math
.SQRT1_2;
And the result
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:
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. :-)
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.
Number
(x).) or negative signs (
-),
NaN, which means
Not a Number.
isNaN
(x)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.
So let's retrieve the numbers and add them 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 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.
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;Math
.random
()ceil
, floor
or round
, which will round it to an integer.Math
.max
(x, y)Math
.min
(x, y)Math
.pow
(x, y)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)pow
still applies.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)Math
.ceil
(x)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)floor
will round it down to 0.Examples of each are below:
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.
Math
.round
(x / 0.1) * 0.1 // Nearest tenthMath
.round
(x / 0.5) * 0.5 // Nearest five tenths (half)Math
.round
(x / 5) * 5 // Nearest fiveMath
.round
(x / 10) * 10 // Nearest tenMath
.round
(x / 20) * 20 // Nearest twentyBelow 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.
var
trs = document
.getElementsByTagName
('tr'
);var
tds1 = trs[2].getElementsByTagName
('td'
);var
num1 = Number
(tds1[0].firstChild
.data
);firstChild
.data
= Math
.round
(num1 / 0.1) * 0.1;firstChild
.data
= Math
.round
(num1 / 0.5) * 0.5;firstChild
.data
= Math
.round
(num1 / 5) * 5;firstChild
.data
= Math
.round
(num1 / 10) * 10;firstChild
.data
= Math
.round
(num1 / 20) * 20;var
tds2 = trs[3].getElementsByTagName
('td'
);var
num2 = Number
(tds2[0].firstChild
.data
);firstChild
.data
= Math
.round
(num2 / 0.1) * 0.1;firstChild
.data
= Math
.round
(num2 / 0.5) * 0.5;firstChild
.data
= Math
.round
(num2 / 5) * 5;firstChild
.data
= Math
.round
(num2 / 10) * 10;firstChild
.data
= Math
.round
(num2 / 20) * 20;toFixed
MethodIf 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.
toFixed
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:
1.2)
toFixed
var
dts = document
.getElementsByTagName
("dt"
);var
dds = document
.getElementsByTagName
("dd"
);firstChild
.data
= Number
(dts[0].getElementsByTagName
("span"
)[0].firstChild
.data
).toFixed
();firstChild
.data
= Number
(dts[1].getElementsByTagName
("span"
)[0].firstChild
.data
).toFixed
(1);firstChild
.data
= Number
(dts[2].getElementsByTagName
("span"
)[0].firstChild
.data
).toFixed
(2);firstChild
.data
= Number
(dts[3].getElementsByTagName
("span"
)[0].firstChild
.data
).toFixed
(-1);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.
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.
alert
(0.6 * 3)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.
((0.6 * 10) * 3) / 10
0.6 × 10 = 6; 6 × 3 = 18; 18 ÷ 10 = 1.8
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.
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.
Math
.floor
(Math
.random
() * array.length
)];Step-by-step, this works out to...
Math
.random
()length
Math
.floor
(...)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.