views:

554

answers:

9

What is meant by magic numbers from a programming point of view.

+31  A: 

Magic numbers are any number in your code that isn't immediately obvious to someone with very little knowledge.

For example, the following piece of code:

sz = sz + 729;

has a magic number in it and would be far better written as:

sz = sz + CAPACITY_INCREMENT;

Some extreme views state that you should never have any numbers in your code except -1, 0 and 1 but I prefer a somewhat less dogmatic view since I would instantly recognise 24, 1440, 86400, 3.1415, 2.71828 and 1.414 - it all depends on your knowledge.

However, even though I know there are 1440 minutes in a day, I would probably still use a MINS_PER_DAY identifier since it makes searching for them that much easier. Whose to say that the capacity increment mentioned above wouldn't also be 1440 and you end up changing the wrong value? This is especially true for the low numbers: the chance of dual use of 37197 is relatively low, the chance of using 5 for multiple things is pretty high.

Use of an identifier means that you wouldn't have to go through all your 700 source files and change 729 to 730 when the capacity increment changed. You could just change the one line:

#define CAPACITY_INCREMENT 729

to:

#define CAPACITY_INCREMENT 730

and recompile the lot.


Contrast this with magic constants which are the result of naive people thinking that just because they remove the actual numbers from their code, they can change:

x = x + 4;

to:

#define FOUR 4
x = x + FOUR;

That adds absolutely zero extra information to your code and is a total waste of time.

paxdiablo
+1 for good example of how not to do it (thedailywtf had a great collection of those just yesterday: http://thedailywtf.com/Articles/Avoiding-Magic-Constants.aspx)
delnan
Yes, I read that one myself. I _especially_ loved the `#define STR1 "1"`, `#define STR9 "1"` at the end (paraphrasing).
paxdiablo
Magic numbers rather than named constants are prone to breakage when changed. If the same number is used for multiple purposes, it is likely to be changed for all purposes and/or only some cases. Named constants significantly reduce this breakage.
BillThor
Yes, as long as the names are intelligent. Calling a constant FOUR is just begging for it to be used for multiple purposes thereby re-introducing easy breakability :-)
paxdiablo
@paxdiablo you made another good case for constants. You mistyped the E mathematical constant. It is NOT: 2.718128 but rather: 2.71828... Using constant saves you from a (hard to find) typo in the code.
Toad
Yes, I meant that as an illustration as to why it's a bad idea .. PigSwill! I call shenanigans (on myself yet). That was error on my part, pure and simple. I'll get it fixed :-)
paxdiablo
Yep, even mathematical or physical constants should be referenced in one place only. Pi isn't likely to change, but the accuracy you need might. And is this particular instance of `x = 3.141529` actually using pi directly, or does it just happen to be the circumference of your 1m wide hoola hoop?
detly
Yes, I would instantly recognise `24` - it's the size of my static data table. Or it was until yesterday, anyway, when I added another item. Now, I'll just search-and-replace all those 24s... Heh - how come there's now 25 hours in a day???
Steve314
Incidentally, what does `1440` refer to? If this is the number of twips to an inch, it seems a bit obscure to expect everyone to know it.
Steve314
In general, this is a really good answer…about *magic constants*. But "magic number" can also refer to special constants in file formats, debugging constants, etc. At the very least, I think it's important to make it clear that the magic numbers you're talking about are only one type of magic number, even from a "programming point of view".
htw
@Steve314: Minutes in a day I guess? `2.71828` looks familiar... but I can't quite put my finger on it.
Mark
Years ago a friend told me of a truly horrible case she'd seen, in which a programmer was putting in magic numbers that were arithmetical combinations of constants. This was bad enough, but then one of the numbers came out to be very close to 3.14159, so he just put in `PI`, which *was* defined. It worked just fine...
Beta
Bods, 1440 _is_ minutes in a day. If it can indeed also be twips/inch, that highlights the danger of the magic numbers further :-) 2.718281828459 is `e`.
paxdiablo
@paxdiablo - 72 points per inch, 20 twips per point, 72*20=1440. I personally recognise this easily, but didn't know the minutes/day. Twips happen a lot dealing with fonts and text metrics in Win32, which I did a fair bit of at one point.
Steve314
Uppercase names are never good.
Lavinski
+4  A: 

"magic numbers" are numbers that appear in statements like

if days == 365

Assuming you didn't know there were 365 days in a year, you'd find this statement meaningless. Thus, it's good practice to assign all "magic" numbers (numbers that have some kind of significance in your program) to a constant,

DAYS_IN_A_YEAR = 365

And from then on, compare to that instead. It's easier to read, and if the earth ever gets knocked out of alignment, and we gain an extra day... you can easily change it (other numbers might be more likely to change).

Mark
"if the earth ever gets knocked out of alignment, and we gain an extra day" -- Odd, that seems to happen about every four years. :)
Thom Smith
The funniest piece of code ever I spied: `#define PI 3.14159 /* make define in case PI ever changes */` :-)
paxdiablo
The earth gets knocked out of alignment every four years?! Wow!
Nick
I memorized pi out to over 250 places. I use it every day. By the way, what is this `#define` you speak of?
Joey Adams
@Nick: It's quite a kick in the pants, let me tell you. Except every hundred years, we get lucky. (Except every four hundred, we don't.) And don't get me started on leap seconds.
Thanatos
+1  A: 

The term magic number is usually used to describe some numeric constant in code. The number appears without any further description and thus its meaning is esoteric.

The use of magic numbers can be avoided by using named constants.

Brian Rasmussen
+2  A: 

Anything that doesn't have a readily apparent meaning to anyone but the application itself.

if (foo == 3) {
    // do something
} else if (foo == 4) {
    // delete all users
}
deceze
A: 

Using numbers in calculations other than 0 or 1 that aren't defined by some identifier or variable (which not only makes the number easy to change in several places by changing it in one place, but also makes it clear to the reader what the number is for).

Shaggy Frog
+2  A: 

Magic numbers are special value of certain variables which causes the program to behave in an special manner.

For example, a communication library might take a Timeout parameter and it can define the magic number "-1" for indicating infinite timeout.

Hemant
+4  A: 

Wikipedia is your friend (Magic Number article)

Roman Hwang
+1, for teaching the OP to fish (hopefully), and not just handing him the fish.
Thanatos
Give a man a fire, he'll be warm for the night. Set a man on fire, he'll be warm for the rest of his life - Terry Pratchett (I think). However, SO should be able to stand alone _even if the rest of the internet disappears!_ By all means link to another source, but I prefer to put some meat in the answer as well.
paxdiablo
+1 for Pratchett!
Paddyslacker
Stack Overflow - your personal Wikipedia search engine!
Pavel Shved
+3  A: 

Most of the answers so far have described a magic number as a constant that isn't self describing. Being a little bit of an "old-school" programmer myself, back in the day we described magic numbers as being any constant that is being assigned some special purpose that influences the behaviour of the code. For example, the number 999999 or MAX_INT or something else completely arbitrary.

The big problem with magic numbers is that their purpose can easily be forgotten, or the value used in another perfectly reasonable context.

As a crude and terribly contrived example:

while (int i != 99999)
{
  DoSomeCleverCalculationBasedOnTheValueOf(i);      

  if (escapeConditionReached)
  {
    i = 99999;
  }
}

The fact that a constant is used or not named isn't really the issue. In the case of my awful example, the value influences behaviour, but what if we need to change the value of "i" while looping?

Clearly in the example above, you don't NEED a magic number to exit the loop. You could replace it with a break statement, and that is the real issue with magic numbers, that they are a lazy approach to coding, and without fail can always be replaced by something less prone to either failure, or to losing meaning over time.

S.Robins
I prefer to call that a sentinel value myself but I see where you're coming from.
paxdiablo
To me, a sentinel value lives in a data structure - typically a key which is too large (or small) to be a valid key. For this loop termination, though, I've seen that described (all too many times) as inherently preferable to `break` because "break is a hidden goto". What does goto achieve? - `PC = target_address;`. To me, these special magic numbers are just disguised and indirect versions of the same thing - assignments that lead execution to a particular point in the code - and as such often noticably less readable and maintainable than simply using `break`.
Steve314
Hard to believe that typing `break` is *less* lazy than setting up that magic number based exit, though.
Steve314
@Steve314: I think you hit on a key point. Regardless of the relative merits, something like a 'break' is inherently more readable. I'm not suggesting that it is less lazy, although like all things in code, it has it's uses. My point though was to highlight that in terms of magic numbers, the maintainability of the code is a major issue, particularly when if you don't understand it's purpose you might change or use a magic number, with unintended side effects as a result.
S.Robins
+4  A: 

There's more than one meaning. The one given by most answers already (an arbitrary unnamed number) is a very common one, and the only thing I'll say about that is that some people go to the extreme of defining...

#define ZERO 0
#define ONE 1

If you do this, I will hunt you down and show no mercy.

Another kind of magic number, though, is used in file formats. It's just a value included as typically the first thing in the file which helps identify the file format, the version of the file format and/or the endian-ness of the particular file.

For example, you might have a magic number of 0x12345678. If you see that magic number, it's a fair guess you're seeing a file of the correct format. If you see, on the other hand, 0x78563412, it's a fair guess that you're seeing an endian-swapped version of the same file format.

The term "magic number" gets abused a bit, though, referring to almost anything that identifies a file format - including quite long ASCII strings in the header.

http://en.wikipedia.org/wiki/File_format#Magic_number

Steve314
I'd argue the second type of magic number (i.e. the ones in file formats) is actually the more common/relevant type.
htw
That may be true - after all, any good programmer will know better than to use a magic number to specify his magic number.
Steve314