Magic Number

A 'magic number' is a literal value that appears in a program. For example:

total = 1.08 * price;

1.08 is a magic number because it appears out of the blue, and it's unclear from this line of code what it means. It's generally better to replace magic numbers with NamedConstants, e.g.

const double TAX_RATE_IN_TEXAS = 1.08;
total = TAX_RATE_IN_TEXAS * price;

This has a couple of advantages: It also has one disadvantage: The refactoring to remove the MagicNumber smell is ReplaceMagicNumberWithSymbolicConstant.


A pet peeve of mine is MagicNumbers with inadequate explanation.

Giving it a symbolic name is a good first step, but it isn't enough. Improving "if (allocation_count < 30)" to "if (allocation_count < MAX_ALLOCATIONS_BEFORE_REALLOCATION)" isn't enough.

When we define

  const unsigned int MAX_ALLOCATIONS_BEFORE_REALLOCATION = 30;
is the perfect place to add adequate explanation.

In particular, I see 3 types of constants in programs:

Are there catchy WikiNames for these categories of numbers?

-- DavidCary


Magic numbers aren't always obvious. If a number appears only once, then it might be okay to highlight it with a comment. Strings can also be treated as magic numbers. For example:

list = "(" + val + "," + val2 + ")";

If you want to change "(" and ")" to, say, "{" and "}", then its better to write code like this:

list = listStart + val + sep + val2 + listEnd;

Here are a couple of rules for determining if a literal is a magic number:

Strict Magic Number rule: Literals (including strings and characters) should only appear on the right hand side of a constant declaration statement.

Practical Magic Number rule: A literal is a not a magic number if the most meaningful variable name for it is the same as the spoken name of the literal.

ZeroOneInfinityRule: The only constants that should appear without a name in a program are 0 and 1, and then only if they are used in integer arithmetic or comparisons (that is, don't use the literals "0" and "1" as success/error codes or in other non-numeric ways).

I don't know about this: computers seem to like the number 2 a lot, as well (but see TwoIsAnImpossibleNumber). It's a good target to shoot for, though.

Can anyone give an example of a literal that is not magic via the Practical Magic Number rule, other than 0, 1, and -1?

Probably things like OPEN_PAREN = "(", FOO_NAME = "foo.name", etc.

In mathematics, sometimes a number is just a number. For instance, in the quadratic formula, (-b +/- sqrt(b^2 - 4ac)) / 2, the best names for 2 and 4 are TWO and FOUR. So they not practically magic.

Certainly. However, such numbers should be contained within a function named QuadraticFormula or somesuch, making intent clear. Just as if you had a constant that was precisely 3.14, you'd name it something so that a new developer would not mistake it for pi.


Apart from actual physical and mathematical constants (pi, e, the speed of light in a vacuum, etc. except that in applications that use these constants, the number of significant digits can be an issue, so they probably should still be defined) it's usually best to read MagicNumbers from a configuration file so that it is easier to change them.

E.g.

static final double DISCOUNT_PERCENT = getProperty( "sales.discount_percent" );
static final double DISCOUNT_FACTOR = 1 - (DISCOUNT_PERCENT / 100);

// ...

salePrice = DISCOUNT_FACTOR * regularPrice;

Even for physical constants, this isn't a bad idea. There was this one time that I needed to eke just a tad more performance out of a program... a 2% boost to the speed of light, and I was set.


For time-related magic numbers it will often be clearer to break it down into an expression eg 60*60*24 instead of 86,400


Also the first two bytes of a Un*x executable. See SheBang.

Similarly, can refer to the first few bytes of a file or protocol unit. Readers of the file/unit can check the value to determine its format, or whether it has a valid format at all. See FileTypingSystem.


Try 'man magic' on a unix/linux box for more info


See Also: ZeroOneInfinityRule, TwoIsAnImpossibleNumber, NamedConstants.


CategoryMath


EditText of this page (last edited May 8, 2013) or FindPage with title or text search