The Day of the Integer
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.

 

Banner

More Puzzles

Sharpen Your Coding Skills
The Best Sub-Array Problem

At first glance this puzzle seems trivial, all you have to do is find a sub-array, in an array of numbers,  that sums to the largest value. It sounds almost too easy to need a solution, let alone [ ... ]


Sharpen Your Coding Skills
Self-Descriptive Arrays

Put on your thinking cap for another set of conundrums that will exercise your coding skills. This time Melvin Frammis introduces his junior partner Bugsy Cottman to some classic number puzzles that c [ ... ]


Sharpen Your Coding Skills
The Post Production Problem

Joe Celko has posed another puzzle that requires you to think like a programmer. This one is all about Post tag machines, which have absolutely nothing to do with mail of any type but a lot to do with [ ... ]


Other Articles


    <ASIN:059680279X>

    <ASIN:0470526912>

    <ASIN:1590597273>

    <ASIN:0596806752>