Is every number in the code considered a “magic number”?

So every number in the code that we are sending to a method as an argument is considered as a Magic Number?
To me, it shouldn’t. I think if some number is let’s say it is for minimum length of user name and we start using “6” in the code…then yeah we have a maintenance problem and here “6” is a magic number….but if we are calling a method that one of its arguments accept an integer for example as the ith member of a collection and then we pass “0” to that method call, in this case I don’t see that “0” as a magic number.
What do you think?

3

If the meaning of the number is very clear in the context, I don’t think it’s a “magic number” problem.

Example: Let’s say you’re trying to get the substring of a string, from the beginning to some token and the code looks like this (imaginary language and library):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>s := substring(big_string, 0, findFirstOccurence(SOME_TOKEN, big_string));
</code>
<code>s := substring(big_string, 0, findFirstOccurence(SOME_TOKEN, big_string)); </code>
s := substring(big_string, 0, findFirstOccurence(SOME_TOKEN, big_string));

In this context, the meaning of the number 0 is clear enough. I suppose you could define START_OF_SUBSTRING and set it to 0, but in this case I think it would be overkill (although it would be the correct approach if you knew that the start of your substring might not be 0, but that depends on the specifics of your situation).

Another example might be if you are trying to determine if a number is even or odd. Writing:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>isEven := x % 2;
</code>
<code>isEven := x % 2; </code>
isEven := x % 2;

is not as strange as:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>TWO := 2;
isEven := x % TWO;
</code>
<code>TWO := 2; isEven := x % TWO; </code>
TWO := 2;
isEven := x % TWO;

Testing negative numbers as

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>MINUS_ONE := -1;
isNegativeInt := i <= MINUS_ONE;
</code>
<code>MINUS_ONE := -1; isNegativeInt := i <= MINUS_ONE; </code>
MINUS_ONE := -1;
isNegativeInt := i <= MINUS_ONE;

also feels weird to me, I’d much rather see

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>isNegativeInt := i <= -1;
</code>
<code>isNegativeInt := i <= -1; </code>
isNegativeInt := i <= -1;

11

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>bool hasApples = apples > 0;
</code>
<code>bool hasApples = apples > 0; </code>
bool hasApples = apples > 0;

It is obvious zero means absence. I find 0 easier to understand than a variable named “absenceValue”.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>for(int i=0; i < arr.length; i++)
</code>
<code>for(int i=0; i < arr.length; i++) </code>
for(int i=0; i < arr.length; i++)

It’s obvious 0 is the starting position. I would be confused by a variable named “firstPosition”. Such a variable would make me wonder if the starting position could change.

I would suggest three key factors in deciding whether something should be a constant declaration:

  1. Is the number something that is precisely and concisely representable
  2. Are there any plausible scenarios under which the value would have to change, but the code would not have to be rewritten
  3. Would someone who sees the number be apt to recognize it more quickly or less quickly than someone who sees a named constant

Something like pi should probably be written as a named constant, rather than as a numeric literal, since a numeric literal is apt to be needlessly verbose, needlessly imprecise, or both. Something like the number of slots in a cache should likely be a named constant (though see note below) to allow for the possibility of expanding the cache without having to modify all the code that uses it. Things like the numbers “4”, “28”, and “29” in the statement if ((year % 4)==0) FebruaryDays = 29; else FebruaryDays = 28; should probably not be named constants, since the expression is almost certainly more readable than if ((year % YearsBetweenLeapYears)==0) FebruaryDays = FebruaryDaysInLeapYear; else FebruaryDays = FebruaryDaysInNonLeapYear;. Note that the maintainers of standards have indicated that the length of February 2100 in that year will not match the above formula, but I would recommend not handling that case unless it would be the only impediment to correctly handling such dates (i.e. the code won’t get tripped by integer overflow or other such problems).

An important caveat with rule #2 is that in some cases code may rely upon hard-coded numbers in a way which cannot readily be represented by a named constant. For example, a method which computes a cross product of two vectors passed as discrete parameters will only be meaningful when used on three-dimensional vectors. The required number of dimensions is not a value that could meaningfully be changed without completely rewriting the routine. Even if one foresaw a possible need for computing the cross product of three 4-dimensional vectors, using a named constant for the value “3” would do little to make it easier to satisfy that need.

4

This, as all principles, is a matter of degree. Generally speaking, number literals in source code are more suspect the larger they are. A maximum length like 10 or a memory address like 0x587FB0 are obviously bad practice – it is almost certain that sooner or later you will have to repeat these values more than once, creating a risk of incompatibility and subtle errors introduced in places that weren’t changed.

0 is at the other end of the scale; it is still suspect but not quite as much.
Are you using 0 as a sentinel value? Then you should probably use a symbolic constant instead, just because the constant can explain what it means. Is it an extremely entrenched cultural agreement such as “0 means successful completion”? That’s probably OK. Does it mean “the first item in a collection”? That may be harmless, but if there is an alternate method such as first() I’d probably prefer that.

2

Every unnamed number that’s not immediately obvious from context is a magic number. Its a little silly to define numbers that have meaning that is immediately obvious from context.

In django (python web framework), I may define some database field with a raw number like:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>firstname = models.CharField(max_length=40)
middlename = models.CharField(max_length=40)
lastname = models.CharField(max_length=40)
</code>
<code>firstname = models.CharField(max_length=40) middlename = models.CharField(max_length=40) lastname = models.CharField(max_length=40) </code>
firstname = models.CharField(max_length=40)
middlename = models.CharField(max_length=40)
lastname =  models.CharField(max_length=40) 

which is clearer (and the recommended practice ) than say

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>MAX_LENGTH_NAME = 40
...
firstname = models.CharField(max_length=MAX_LENGTH_NAME)
middlename = models.CharField(max_length=MAX_LENGTH_NAME)
lastname = models.CharField(max_length=MAX_LENGTH_NAME)
</code>
<code>MAX_LENGTH_NAME = 40 ... firstname = models.CharField(max_length=MAX_LENGTH_NAME) middlename = models.CharField(max_length=MAX_LENGTH_NAME) lastname = models.CharField(max_length=MAX_LENGTH_NAME) </code>
MAX_LENGTH_NAME = 40
...
firstname = models.CharField(max_length=MAX_LENGTH_NAME)
middlename = models.CharField(max_length=MAX_LENGTH_NAME)
lastname =  models.CharField(max_length=MAX_LENGTH_NAME) 

as I’m unlikely to ever need to change the length (and can always compare to the max_length of the field). If I do need to change the length of the field after initially deploying the application, I need to change it in exactly one location per field in my django code, and then additionally write a migration to change the schema of the DB. If I ever need to reference max_length of a defined field of a type of object, I can do it directly — if those fields were defining a Person class, I can use Person._meta.get_field('firstname').max_length to obtain the max_length being used (which is defined in one place). The fact that the same 40 was used for multiple fields is irrelevant as I may want to change them independently. The length of firstname should never depend on the length of middlename or lastname; they are separate values and can change independently.

Often array indices can use unnamed numbers; like if I have a CSV file of data that I want to put in a python dictionary, with the first element in the row as the dictionary key I would write:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>mydict = {}
for row in csv.reader(f):
mydict[row[0]] = row[1:]
</code>
<code>mydict = {} for row in csv.reader(f): mydict[row[0]] = row[1:] </code>
mydict = {}
for row in csv.reader(f):
    mydict[row[0]] = row[1:]

Sure I could name index_column = 0 and do something like:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>index_col = 0
mydict = {}
for row in csv.reader(f):
mydict[row[index_col]] = row[:index_col] + row[index_col+1:]
</code>
<code>index_col = 0 mydict = {} for row in csv.reader(f): mydict[row[index_col]] = row[:index_col] + row[index_col+1:] </code>
index_col = 0
mydict = {}
for row in csv.reader(f):
    mydict[row[index_col]] = row[:index_col] + row[index_col+1:]

or worse define after_index_col = index_col + 1 to get rid of the index_col+1, but that doesn’t make the code clearer in my view. Also, if I give the index_col a name, I better make the code work even if the column is not 0 (hence the row[:index_col] + part).

9

Sometimes numbers in code will never be changed. With integer values, using symbolic names would obscure the code. For example:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code> radians= (degrees * M_PI) / 180;
</code>
<code> radians= (degrees * M_PI) / 180; </code>
   radians= (degrees * M_PI) / 180;

and

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code> degrees_fahrenheit= 32 + (degrees_celsius * 9) / 5;
</code>
<code> degrees_fahrenheit= 32 + (degrees_celsius * 9) / 5; </code>
   degrees_fahrenheit= 32 + (degrees_celsius * 9) / 5;

Having code reflect the conversion equation maximizes readability.

I’ve been reading the answers raising my eyebrows. I think all of them, including the Wikipedia page, are wrong.

To me a magic number is something very specific that has nothing to do with whether a constant has been defined for it or not. And I did not make this up myself.

A magic number is the computer science equivalent of in-band signaling. It means there is a number in a domain (say, integers) that gets assigned (semantically) a different meaning than its value. This is always problematic and often a hack to overcome some shortcoming in the programming language, it is an optimization or it’s just a lazy shortcut.

Example: You have a variable Age and you want to abuse it to tell whether the person is still alive or not. This is where you go wrong already but you may be living in the 1960s and be short on memory. You come up with the idea of using 200 to signal someone is dead. That would make 200 a magic number.

In this case it may be obvious there is something about 200 because nobody makes 200 but the potential problems are obvious. You have to be aware of this hack every time you do something with ages. You can no longer just calculate an average age without being aware of it for example.

The classic example of this being a problem is an old AT&T phone system that used a particular frequency not often used in speech to terminate the call. This did not work out well, people whistling over the phone was enough to drop the call.

2

As in everything, context is everything. A couple of simple rules of thumb should be kept in mind: 1) the more frequently it is used, the more likely it is to deserve a name, 2) if the reason why it is that number instead of another number isn’t clear without knowing more than is in the function/method, it deserves a name to explain it.

0 seldom needs a name, because it’s generally clear from context, but there can certainly be circumstances where it’s unclear, where a name or a comment is necessary to explain why it was used. Determining even/odd with a modulo 2 is clear, giving a 50% discount might not be clear whether it is done with a multiplication or a division. Context is everything.

In your specific example, zero would represent the first element of the collection, but you might want to have a name that explains why the first and not the last…

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật