Are all magic numbers created the same

code-quality

On a recent project, I needed to convert from bytes to kilobytes kibibyte. The code was straightforward enough:

var kBval = byteVal / 1024;

After writing that, I got the rest of the function working & moved on.

But later on, I started to wonder if I had just embedded a magic number within my code. Part of me says it was fine because the number is a fixed constant and should be readily understood. But another part of me thinks it would have been super clear if wrapped in a defined constant like BYTES_PER_KBYTE.

So are numbers that are well known constants really all that magical or not?


Related questions:

When is a number a magic number? and Is every number in the code considered a "magic number"? – are similar, but are much broader questions than what I'm asking. My question is focused on well-known constant numbers which is not addressed in those questions.

Eliminating Magic Numbers: When is it time to say "No"? is also related, but is focused on refactoring as opposed to whether or not a constant number is a magic number.

Best Answer

Not all magic numbers are the same.

I think in that instance, that constant is OK. The problem with magic numbers is when they are magic, i.e. it is unclear what their origin is, why the value is what it is, or whether the value is correct or not.

Hiding 1024 behind BYTES_PER_KBYTE also means you don't see instantly if it is correct or not.

I would expect anyone to know immediately why the value is 1024. On the other hand, if you were converting bytes to megabytes, I would define the constant BYTES_PER_MBYTE or similar because the constant 1,048,576 isn't so obvious that its 1024^2, or that it's even correct.

The same goes for values that are dictated by requirements or standards, that are only used in one place. I find just putting the constant right in place with a comment to the relevant source to be easier to deal with than defining it elsewhere and having to chase both parts down, e.g.:

// Value must be less than 3.5 volts according to spec blah.
SomeTest = DataSample < 3.50

I find better than

SomeTest = DataSample < SOME_THRESHOLD_VALUE

Only when SOME_THRESHOLD_VALUE is used in multiple places does the tradeoff become worth it to define a constant, in my opinion.