Monday, September 26, 2011

Just say no to "magic numbers"

It is unacceptable to use "magic numbers" in your source code. When dealing with trivial programs, using a naked number doesn't look like such a big deal (the code is short and, if well commented, the intent of the programmer is clear) but it is still a very bad habit to develop. The problem is both clearer to see and greatly magnified once the size of the code in question is larger.

A "magic number" is an unnamed constant that appears in the source code.

The appearance of a naked number in the code obscures the reasoning behind choosing that number. Why are you running a loop from 5 to 8? Why not from 0 to 3 instead?What's so special about 5 and 8?

Using a "magic number" can also introduce subtle errors and inconsistencies. Imagine a programming team working on an application that relies heavily on mathematical calculations. One programmer uses 3.14 to represent pi. Another uses 3.1415. Which one is correct? Will changing the code mid-project to use one particular value cause portions of the code to break?

Yet another problem with "magic numbers" is that their usage makes the code more difficult to maintain and extend. One of the largest cell phone carrier currently allows users to select five or ten favorite contact numbers for which they will not be billed minutes. Let's say that a competitor wishes to offer a similar service but to go one better and allow their customers twelve free contact numbers and the programmers simply hardcode 12 in all of the lists where these contact numbers are handled. Later on, the company realizes that this is unprofitable and wishes to reduce the quanity of free contact numbers to ten. There are 12s which refer to the number of months in a year and 12s which refer to the free contact numbers lists. Are the original programmers still on staff? Do they remember which 12s are which? They can't do a global search and replace on all 12s: that would have the side effect of shortening the calendar year. How long will the changes take to implement since someone now needs to go through all of the thousands of lines of code?

Instead of dropping "magic numbers" into your code, make a section of constant declarations at the top of your class or method.

Not this

     for ( int ctr = 5; ...

but this

     final static int LOWER_LIMIT = 5;
     // More code here
     for ( int ctr = LOWER_LIMIT; ...

Using constants like this makes the code easier to read and understand and easier to change and maintain as the project over time.

Having said all of that, is it ever permissible to use a "magic number"? Yes, under certain conditions...
  • You can use 0 to initialize a loop control counter:

         for ( int ctr = 0; ...

  • You can use 2 to determine if another number is odd or even:

         if ( testVariable % 2 == 0 )

  • You can simple arithematic constants, such as calculating the volume of a sphere :

         v = 4 * Math.PI * Math.pow(r, 3) / 3;