Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Magic number (programming)
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
=== Random shuffle example === For example, if it is required to randomly shuffle the values in an array representing a standard pack of [[playing cards]], this [[pseudocode]] does the job using the [[Fisher–Yates shuffle]] algorithm: '''for''' i '''from''' 1 '''to''' 52 j := i + randomInt(53 - i) - 1 a.swapEntries(i, j) where <code>a</code> is an array object, the function <code>randomInt(x)</code> chooses a random integer between 1 and ''x'', inclusive, and <code>swapEntries(i, j)</code> swaps the ''i''th and ''j''th entries in the array. In the preceding example, <code>52</code> and <code>53</code> are magic numbers, also not clearly related to each other. It is considered better programming style to write the following: ''int'' deckSize:= 52 '''for''' i '''from''' 1 '''to''' deckSize j := i + randomInt(deckSize + 1 - i) - 1 a.swapEntries(i, j) This is preferable for several reasons: * '''Better readability'''. A programmer reading the first example might wonder, ''What does the number 52 mean here? Why 52?'' The programmer might infer the meaning after reading the code carefully, but it is not obvious.<ref name="Paul_2002_SYMBOLS"/> Magic numbers become particularly confusing when the same number is used for different purposes in one section of code. * '''Easier to maintain'''. It is easier to alter the value of the number, as it is not duplicated. Changing the value of a magic number is error-prone, because the same value is often used several times in different places within a program.<ref name="Paul_2002_SYMBOLS"/> Also, when two semantically distinct variables or numbers have the same value they may be accidentally both edited together.<ref name="Paul_2002_SYMBOLS"/> To modify the first example to shuffle a [[Tarot]] deck, which has 78 cards, a programmer might naively replace every instance of 52 in the program with 78. This would cause two problems. First, it would miss the value 53 on the second line of the example, which would cause the algorithm to fail in a subtle way. Second, it would likely replace the characters "52" everywhere, regardless of whether they refer to the deck size or to something else entirely, such as the number of weeks in a Gregorian calendar year, or more insidiously, are part of a number like "1523", all of which would introduce bugs. By contrast, changing the value of the <code>deckSize</code> variable in the second example would be a simple, one-line change. * '''Encourages documentation'''.<ref name="Paul_2002_SYMBOLS"/> The single place where the named variable is declared makes a good place to document what the value means and why it has the value it does. Having the same value in a plethora of places either leads to duplicate comments (and attendant problems when updating some but missing some) or leaves no ''one'' place where it's both natural for the author to explain the value and likely the reader shall look for an explanation. * '''Coalesces information'''. The declarations of "magic number" variables can be placed together, usually at the top of a function or file, facilitating their review and change.<ref name="Paul_2002_SYMBOLS"/> * '''Detects [[typo]]s'''. Using a variable (instead of a literal) takes advantage of a compiler's checking. Accidentally typing "62" instead of "52" would go undetected, whereas typing "<code>dekSize</code>" instead of "<code>deckSize</code>" would result in the compiler's warning that <code>dekSize</code> is undeclared. * '''Reduces typings'''. If a [[Integrated development environment|IDE]] supports [[code completion]], it will fill in most of the variable's name from the first few letters. * '''Facilitates parameterization'''. For example, to generalize the above example into a procedure that shuffles a deck of any number of cards, it would be sufficient to turn <code>deckSize</code> into a parameter of that procedure, whereas the first example would require several changes. '''function''' shuffle ('''int''' deckSize) '''for''' i '''from''' 1 '''to''' deckSize j := i + randomInt(deckSize + 1 - i) - 1 a.swapEntries(i, j) Disadvantages are: * '''Breaks locality'''. When the named constant is not defined near its use, it hurts the locality, and thus comprehensibility, of the code. Putting the 52 in a possibly distant place means that, to understand the workings of the "for" loop completely (for example to estimate the run-time of the loop), one must track down the definition and verify that it is the expected number. This is easy to avoid (by relocating the declaration) when the constant is only used in one portion of the code. When the named constant is used in disparate portions, on the other hand, the remote location is a clue to the reader that the same value appears in other places in the code, which may also be worth looking into. * '''Causes verbosity'''. The declaration of the constant adds a line. When the constant's name is longer than the value's, particularly if several such constants appear in one line, it may make it necessary to split one logical statement of the code across several lines. An increase in verbosity may be justified when there is some likelihood of confusion about the constant, or when there is a likelihood the constant may need to be changed, such as [[code reuse|reuse]] of a shuffling routine for other card games. It may equally be justified as an increase in expressiveness. * '''Performance considerations'''. It may be slower to process the expression <code>deckSize + 1</code> at run-time than the value "53". That being said, most modern compilers will use techniques like [[constant folding]] and [[loop optimization]] to resolve the addition during compilation, so there is usually no or negligible speed penalty compared to using magic numbers in code. Especially the cost of debugging and the time needed trying to understand non-explanatory code must be held against the tiny calculation cost.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)