Magic Numbers
A magic number is a hard-coded numeric value (text value in some cases) in the code that may change at a later stage. It seems arbitrary and has no context or meaning. It is hard to update.
Example: area= 3.142 * radius *radius; //3.142 is a magic number
One of the most important aspects of code quality is how it conveys intention. Magic numbers hide intention so they should be avoided.
The recommended approach is to create a constant to represent the value. This will improve the readability of the code and make it easier to modify in the future.
We've got a couple of magic numbers in example 1. It's not obvious what the 9.95 charge is. The 0.10 may be a sales tax or something else like a late fee. But we are not sure about the purpose of these numbers.
Example 1
double getTotal(double subtotal) {
double total = subtotal + 9.95; // 9.95is a magic number
return total + (total * 0.10); // 0.10 is a magic number
}
Here are refactored constants making it clear what the values represent:
final double SHIPPING_FEE = 9.95; // 9.95 is for shipping fee
final double SALES_TAX = 0.10; // 0.10 is for sales tax
double getTotal(double subtotal) {
double total = subtotal + SHIPPING_FEE;
return total + (total * SALES_TAX);
}
Example 2
double potentialEnergy(double mass, double height) {
return mass * height * 9.81; // 9.81 is a magic number
}
Replace this number with a constant that has a human-readable name explaining the meaning of the number.
static final double GRAVITATIONAL_FORCE = 9.81;
double potentialEnergy(double mass, double height) {
return mass * height * GRAVITATIONAL_FORCE;
}
Solution for magic numbers
Rename the constants/magic numbers with meaningful and intention-revealing names.
Benefits of refactoring Magic numbers
The symbolic constant can serve as a live documentation of the meaning of its value.
It’s much easier to change the value of a constant than to search for this number throughout the entire codebase, without the risk of accidentally changing the same number used elsewhere for a different purpose.
Reduce duplicate use of a number or string in the code. This is especially important when the value is complicated and long (such as 3.14159 or 0xCAFEBABE).
Good to Know - Not all numbers are magical.
If the purpose of a number is obvious, there’s no need to replace it. A classic example is
for( i=0; i<count; i++) {….….}
void doSomething ( int v) //Non compliant – can’t understand what is v
{ …..
}
If(var == 42) { // noncomplaint – 42 is a magic number
…...
}
Good code or Compliant Solution
enum Status {
STATUS_KO = 0,
STATUS_OK = 42,
};
void doSomething(Status var){
const int maxIterations =42; // Compliant – in a declaration
for( int i=0; I < maxIterations ;i++) { // Compliant : 0 is excluded, and maxIterations
// is a named constant
}
if (STATUS_OK == var) { // Compliant - number comes from an enum
// ...
}
}
Questions on Magic Numbers
1. A ----------------- is a hard-coded numeric value (text value in some cases) in the code that may change at a later stage. It seems like arbitrary and has no context or meaning. It is hard to update.
a) magic number
b) Prime Number
c) Natural Number
d) Real Number
2. Find out the magic numbers in the following code
const num = 74;
const number = num / 2;
a) 74
b) 2
c) None of the above
d) Both a and b
3. Check out the magic numbers in the code
double getTotal(double subtotal) {
double total = subtotal + 9.95;
return total + (total * 0.10); }
a) 0.10
b) 9.95
c) 0.10 and 9.95
d) No magic numbers in the code
4. Magic numbers should be avoided because it is
a) It is difficult to understand and maintain
b) It hides the intention of the code
c) The changes in the code is also hard
d) All of the above
5. Replace a number with a constant that has a human-readable name explaining the meaning of the number.
a) True
b) False