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.
No, they aren't.

A magic number in that context would be a number that has an unexplained meaning. In your case, it specifies the precision, which clearly visible.

A magic number would be something like:

```
int calculateFoo(int input)
{
  return 0x3557 * input;
}

```

You should be aware that the phrase "magic number" has multiple meanings. In this case, it specifies a number in source code, that is unexplainable by the surroundings. There are other cases where the phrase is used, for example in a file header, identifying it as a file of a certain type.