Section E. Working with numbers


E. Working with numbers

Numbers are fairly straightforward to work with. Note that JavaScript makes no distinction between integers and floating-point values; they're both numbers. Calculations work as expected, and you can influence their order by the use of parentheses:

var sum = var1 + var2 * var3; var sum = (var1 + var2) * var3; 


The first line of code multiplies var2 and var3, and then adds var1 to the result. The second line adds var1 and var2, and multiplies the result by var3. No surprises here.

Rounding Errors

When you perform calculations with decimals, you may come across the infamous rounding error. For complicated reasons, the simple calculation 0.05 + 0.01 does not yield 0.06, as you'd expect, but 0.060000000000000005. Similarly, -0.07+0.05+0.02 does not yield 0, but -3.469446951953614e-18.

Solution: round the result in one of the ways described below before showing it to the user.

The upcoming JavaScript 2.0 specification will address this problem.


Octal and hexadecimal numbers

JavaScript also allows you to use octal and hexadecimal numbers. Any number that starts with a 0 is octal; any number that starts with 0x is hexadecimal. Take this example:

var test1 = 042; var test2 = 0x42; alert(test1 + ' ' + test2); 


The alert now says '34 66', since the octal number 42 is decimal 34, while the hexadecimal number 42 is decimal 66.

Octal Errors

People will never add 0x to their numbers accidentally, but adding an accidental leading 0 is possible. When I created Site Survey I was asked to add an extra variable to hold the project number. I duly did so, but the client complained that it didn't work as expected. It turned out that he'd entered the (octal) number 042, which was returned to the server as 34. I told him to either remove the leading 0 or to make the variable a string.


The Math Object

Instead of treating the complete Math object, I'll just highlight a few methods that are useful in everyday Web development. For a complete overview, see http://www.w3schools.com/jsref/jsref_obj_math.asp.


The Math object

JavaScript has a Math object that contains methods for more complex mathematical operations (e.g., Math.sqrt(4) gives the square root of 4) and properties for constants (e.g., Math.PI holds the number pi). Although the Math object allows many mathematical calculations, you'll rarely need those in a Web sitewell, maybe if you want to calculate the path of a circular animation, but how often does that happen?

Math.round(), Math.floor(), and Math.ceil()

The Math object contains three methods for rounding numbers: Math.round(), Math.floor(), and Math.ceil().

Math.round() always rounds to the nearest integer:

alert(Math.round(1.4)); // yields 1; the nearest integer alert(Math.round(1.6)); // yields 2; the nearest integer 


Math.floor() always rounds down (including when working with negative numbers):

alert(Math.floor(1.6)); // yields 1 alert(Math.floor(-1.6)); // yields -2 


Math.ceil() always rounds up (including when working with negative numbers):

alert(Math.ceil(1.6)); // yields 2 alert(Math.ceil(-1.6)); // yields -1 


Although these methods work on numbers, you can also specify a string as the argument. As usual, data-type conversion makes this possible:

alert(Math.floor('1.6')); // also yields 1; 


Math.random()

Math.random() gives a random number between 0 and 1. I use it in XMLHTTP Speed Meter to generate a random animation:

[XMLHTTP Speed Meter, line 111]

var fluctuationDirection = (Math.random() < .5) ? 1 : -1; 


If the random number is smaller than 0.5, the animation should take one step in the positive direction; if it's larger, it should take one step in the negative direction.

If you need a random number between 0 and 10, simply multiply the value of Math.random() by 10:

var randomNumber = Math.random() * 10; 


Math.abs()

Math.abs(x) gives the absolute (i.e., non-negative) value of the number x. I use this in XMLHTTP Speed Meter, too, because I want to calculate the direction of an animation:

[XMLHTTP Speed Meter, lines 84-86]

var distance = Mbit - currentMbit; var direction = distance/Math.abs(distance); if (!direction) return; 


currentMbit is the current position of the animation, and Mbit the desired position. Subtracting one from the other yields the distance the animation has to go. But I also want to know the direction of the animation, so I divide distance (which may be positive or negative) by the absolute value of distance (which is always positive). This division yields 1 or -1, which gives me the direction of the animation.

If the outcome is 0 (i.e., the current and desired position are the same) I end the function.

toFixed()

The toFixed() method converts a number to a string with the specified amount of decimals. This is especially useful when working with prices; for example, price.toFixed(2) gives output that's suitable for a price.

Contrary to the Math methods we just discussed, toFixed() is a method of a Number object. This doesn't work:

   var x = '4';  alert(x.toFixed(2)); 


toFixed() cannot be used on strings, and therefore this code gives an error message.

I use the method in Sandwich Picker. I want to show the total price of the user's order in the correct place, and I want it to have two decimals and no weird rounding errors. I wrote a function createReadablePrice() that takes care of this operation:

[Sandwich Picker, lines 204-208]

function createReadablePrice(price) {    price = price.toFixed(2);    price = price.replace(/\./,',');    return price; } 


The function receives a price and makes sure it has two decimals. Then it replaces the dot with a comma. (In Dutch, the comma is the decimal separator.)

Note that this function receives a number but returns a string.

parseInt() and parseFloat()

Two global methods wrap up this quick overview: parseInt() and parseFloat(). Both receive a string as an argument and extract a number: an integer and a floating-point number, respectively.

The real power of these methods is that the strings they receive may contain non-numerical characters, as in these examples:

alert(parseInt("3.54 apples")); // yields 3 alert(parseFloat("3.54 apples")); // yields 3.54 


Both methods start at the left of the string. If the first character is not a number or a minus sign (or, in the case of parseFloat(), a decimal dot), they return NaN.

If the first character is valid, the methods continue reading out the string until they encounter a non-numeric character (or, in the case of parseInt(), a decimal dot). Once they encounter such a character, they return the number they extracted.



ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ISBN: N/A
EAN: N/A
Year: 2005
Pages: 116

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net