Question: I have a function like this:

```
float_as_thousands_str_with_precision(value, precision)

```

If I use it like this:

```
float_as_thousands_str_with_precision(volts, 1)
float_as_thousands_str_with_precision(amps, 2)
float_as_thousands_str_with_precision(watts, 2)

```

Are those 1/2s magic numbers?

Answer: 
Yes, they are magic numbers. It's obvious that the numbers 1 and 2 specify precision in the code sample but not why. Why do you need amps and watts to be more precise than volts at that point?

Also, avoiding magic numbers allows you to centralize code changes rather than having to scour the code when for the literal number 2 when your precision needs to change.

I would propose something like:

```
HIGH_PRECISION = 3;
MED_PRECISION = 2;
LOW_PRECISION = 1;

```

And your client code would look like:

```
float_as_thousands_str_with_precision(volts, LOW_PRECISION )
float_as_thousands_str_with_precision(amps, MED_PRECISION )
float_as_thousands_str_with_precision(watts, MED_PRECISION )

```

Then, if in the future you do something like this:

```
HIGH_PRECISION = 6;
MED_PRECISION = 4;
LOW_PRECISION = 2;

```

All you do is change the constants...

**But to try and answer the question in the OP title:**

IMO the only numbers that can truly be used and not be considered "magic" are -1, 0 and 1 when used in iteration, testing lengths and sizes and many mathematical operations. Some examples where using constants would actually obfuscate code:

```
for (int i=0; i<someCollection.Length; i++) {...}

if (someCollection.Length == 0) {...}

if (someCollection.Length < 1) {...}

int MyRidiculousSignReversalFunction(int i) {return i * -1;}

```

Those are all pretty obvious examples. E.g. start and the first element and increment by one, testing to see whether a collection is empty and sign reversal... ridiculous but works as an example. Now replace all of the -1, 0 and 1 values with 2:

```
for (int i=2; i<50; i+=2) {...}

if (someCollection.Length == 2) {...}

if (someCollection.Length < 2) {...}

int MyRidiculousDoublinglFunction(int i) {return i * 2;}

```

Now you have start asking yourself: Why am I starting iteration on the 3rd element and checking every other? And what's so special about the number 50? What's so special about a collection with two elements? the doubler example actually makes sense here but you can see that the non -1, 0, 1 values of 2 and 50 immediately become magic because there's obviously something special in what they're doing and we have no idea why.
A literal numeral IS NOT a magic number when:

* it is used one time, in one place, with very clear purpose based on its context
* it is used with such common frequency and within such a limited context as to be widely accepted as not magic (e.g. the +1 or -1 in loops that people so frequently accept as being not magic).
* some people accept the +1 of a zero offset as not magic. I do not. When I see variable + 1 I still want to know why, and ZERO\_OFFSET cannot be mistaken.

As for the example scenario of:

float\_as\_thousands\_str\_with\_precision(volts, 1)

And the proposed 

float\_as\_thousands\_str\_with\_precision(volts, HIGH\_PRECISION)

The 1 is magic if that function for volts with 1 is going to be used repeatedly for the same purpose. Then sure, it's "magic" but not because the meaning is unclear, but because you simply have multiple occurences.

Paul's answer focused on the "unexplained meaning" part thinking HIGH\_PRECISION = 3 explained the purpose. IMO, HIGH\_PRECISION offers no more explanation or value than something like PRECISION\_THREE or THREE or 3. Of course 3 is higher than 1, but it still doesn't explain WHY higher precision was needed, or why there's a difference in precision. The numerals offer every bit as much intent and clarity as the proposed labels.

Why is there a need for varying precision in the first place? As an engineering guy, I can assume there's three possible reasons: (a) a true engineering justification that the measurement itself is only valid to X precision, so therefore the display shoulld reflect that, or (b) there's only enough display space for X precision, or (c) the viewer won't care about anything higher that X precision even if its available.

Those are complex reasons difficult to capture in a constant label, and are probbaly better served by a comment (to explain why something is beng done).

IF the use of those functions were in one place, and one place only, I would not consider the numerals magic. The intent is clear.

For reference:

A literal numeral IS magic when 

* "Unique values with unexplained meaning or multiple occurrences which
could (preferably) be replaced with named constants." <http://en.wikipedia.org/wiki/Magic_number_%28programming%29> (3rd bullet)