The Day of the Integer
Written by Ian Elliot
Thursday, 16 December 2010
Article Index
The Day of the Integer
Solution

Solution

The problem with the code is that the programmer looked at the parseInt function and assumed that it was just a string to integer conversion facility. If you read the documentation you will find that it is also able to convert a string in other bases than 10 to an integer. To make use of this you have to specify the radix (i.e. base) as the second parameter.

For eample:

`b="101";alert(parseInt(b,2));`

displays 5 because 101 is 5 in binary and

`var h="AF";alert(parseInt(h,16));`

displays 175 because AF is 175 in hex.

You can even do very strange base conversions that aren't normally encountered.

For example:

`var h="AG";alert(parseInt(h,17));`

which displays 186 because AG is 186 in base 17. You can use letters to represent numerals - A is 10, B is 11 and so on.

This is, of course, all very useful. Unfortunately there is a small problem. If you omit the radix then base ten is assumed unless the string starts with 0x when hexadecimal is used or 0 when octal is used. Both of these conventions go back a long way into computing's history but the octal convention is dangerous because dates and other fixed format numbers are often written with leading zeros.

What this means is using ParseInt without a radix specified  is dangerous.

For example, if the day string is "01" this is parsed as octal 01 which is just the same as decimal 1. Things doesn't work out quite as well when we reach "08" however because 8 should never occur in an octal number. In most cases the parseInt("08") returns zero and so does parseInt("09") which again should never occur in octal.

The rule is that that whenever parseInt reaches a character that isn't a valid numeral it stops parsing the string and returns the result of the conversion so far. Hence for "08" and "09" it returns zero.

As a two digit date string is only interpreted as octal when it starts with a zero days "08" and "09" are the only two that actually cause a problem. All other dates work perfectly and are either interpreted as decimal or octal numbers that work out to the same value as decimal would have given anyway.

The parseInt function is implemented in slightly different ways on different browser. In particular IE9 returns the decimal conversion of "08" i.e. eight but still follows the "return the conversion so far" rule of any other non-numeric characters. This makes our example problem work but who knows what other code this behaviour breaks.  The good news is that in ECMAScript 5 strings starting with "0" are not parsed as octal - you have to specify the radix.

At the moment you have to be careful how you use parseInt.

Pattern

I suppose you could conclude that the only pattern that avoids such problems is to always read the exact definition of any functions you are using. More specifically you should never assume that an optional parameter defaults to the desired behaviour if you leave it out.

In this case the simplest fix for the problem is indeed to specify the optional parameter. That is:

`var daynum=parseInt(day,10);alert(100/daynum);`

In fact don't think of parseInt as convert to integer. instead think of parseInt(  ,10) as convert to decimal integer. You could even create your own foolproof parseInt10 function using:

`var parseInt10=function(i){                 return parseInt(i,10)};`

You could even override the standard global parseInt function to provide the ECMAscript functionality in any browser but an even better idea is to use the Number function. This always performs a decimal conversion but it also has its problems. Number will convert a wider class of objects into a number including date objects. It also will return NaN if the object cannot be converted to a number and this includes any string with non-numeric characters.

In this case however we are sure that the parameter will be a correctly formatted string and so Number is perfectly safe and it works on all browsers and ECMAScript 5.

In general however converting a string to a number can be a tricky task in JavaScript.

More Puzzles

 PythonProgrammer Puzzle - Python Swallows A GlobalHere's a teaser that poses a practical problem - one that crops up in everyday Python programming. See if you can work out the answer before looking at its solution and the pattern to follow to avoid  [ ... ] + Full Story Sharpen Your Coding SkillsTaxicab Geometry ProblemsIn the conference season, developers face the perennial problem of getting from one hotel to another to meet colleagues. How good is your ability to write procedures to find shortest distance in a cit [ ... ] + Full Story PythonPython Puzzle - Where Did The Time Go?A Python programming puzzle to get you up to speed. This one is all about time keeping, or is it? There are some strange things that go on in Python when you aren't paying attention.  + Full Story Other Articles

<ASIN:059680279X>

<ASIN:0470526912>

<ASIN:1590597273>

<ASIN:0596806752>

Last Updated ( Friday, 07 January 2011 )