Sunday, October 16, 2011

Playing with Numbers in Javascript

Handling numbers is a very basic task for (web)developers, but how exactly is this working in Javascript?

Numbers are "double-precision 64-bit format IEEE 754 values". Let's see some examples how it can handle things:

console.log( 0.1 + 0.2 ); // 0.30000000000000004

// but:
console.log( (0.1*10 + 0.2*10) / 10 ); // 0.3

console.log( parseInt("123", 10) ); // 123
console.log( parseInt("010", 10) ); // 10

// The parseInt() and parseFloat() functions parse a string until 
// they reach a character that isn't valid for the specified number 
// format, then return the number parsed up to that point.
console.log( parseInt("test: 123", 10) ); // NaN
console.log( parseInt("test: 010", 10) ); // NaN
console.log( parseInt(1.23, 10) ); // 1
console.log( parseInt(1.99, 10) ); // 1
console.log( parseInt(-5.1) ); // -5
console.log( Math.floor(-5.1) ); // -6 (!!)
console.log( parseFloat("1.67") ); // 1.67 (Number)
console.log( parseInt("456test: 010", 10) ); // 456

// converting without parseInt() or parseFloat()
console.log( "456 test: 010" * 1 ); // NaN
console.log( 1 * "456 test: 010" ); // NaN
console.log( 1 * "    456     " ); // 456 (space characters are allowed)
console.log( 1 * "    .456     " ); // 0.456
console.log( 1 * "    . 456     " ); // NaN
console.log( 1 + "2" + 3 + 4 ); // 1234
console.log( 1 - "2" + 3 + 4 ); // 6 (-1 + 3 + 4)
console.log( 1 * "2" + 3 + 4 ); // 9 (2 + 3 + 4)
console.log( 1 / "2" + 3 + 4 ); // 7.5 (0.5 + 3 + 4)
console.log( 5 % "3" ); // 2
console.log( 5 % " 3 " ); // 2
console.log( 5 % " 3a " ); // NaN

console.log( parseInt("010") ); // 8 (!!)
console.log( parseFloat("010") ); // 10 (!!)
console.log( parseFloat("010.123") ); // 10.123
console.log( parseInt("11",2) ); // 3 (binary to integer)
console.log( parseFloat("11") ); // 11


// converting with unary operator
console.log( +"11" ); // 11
console.log( typeof +"11" ); // number
console.log( +"11a" ); // NaN
console.log( -"11" ); // -11
console.log( typeof -"11" ); // number

// other number types
console.log( parseInt("hello", 10) ); // NaN
console.log( typeof parseInt("hello", 10) ); // Number (!!)
console.log( parseInt("hello", 10) * 1 + 5 ); // NaN (NaN is toxic..)
console.log( isNaN(parseInt("hello", 10)) ); // true
console.log( isNaN(10) ); // false
console.log(1/0); // Infinity
console.log(-1/0); // -Infinity



My conclusion are:
  • If I'm working with floats I should round them to a limited precision.
  • The safest way to convert strings to numbers is to use parseInt() or parseFloat().
  • The parseInt() function has a second argument wich defines the base of the number system that the string has. I should always set this value, just to be clear and avoid some untrackable bugs..
  • Before I use parseInt() it's a good idea to clean the string from any letters (this is quite task dependent). I should care about this, because if a string made up of numbers it's fine. But it could have some toxic character value in it and that could kill the whole process. So be careful.
  • If I call parseInt on a float number, it will return always the integer part of the number. So it's not the same as Math.floor()
  • parseInt() on a string like (123a456) will only return the first few characters parsed as numbers.
  • Converting numbers with only " * 1" is not safe. Only if I can be absolutely sure that the string will only contain number characters or space.
  • parseFloat() uses always 10 as the base number system
  • I can convert strings into numbers with an unary operator (Wow..)
  • NaN is toxic. Very toxic.. avoid it at all cost (unless this is what I want)
  • There is an Infinity type number in Javascript but I don't quite know what is it good for. (Maybe just to indicate that the number is too big..do something with it because javascript can't handle it)

I have read the basic number handling tests on: developer.mozilla.org and I have made up some others on my own.

1 comment: