数字何时不是魔术?

the*_*ine 2 magic-numbers

我有这样的功能:

float_as_thousands_str_with_precision(value, precision)
Run Code Online (Sandbox Code Playgroud)

如果我像这样使用它:

float_as_thousands_str_with_precision(volts, 1)
float_as_thousands_str_with_precision(amps, 2)
float_as_thousands_str_with_precision(watts, 2)
Run Code Online (Sandbox Code Playgroud)

那些1/2的神奇数字吗?

Pau*_*sik 5

是的,他们是神奇的数字.很明显,数字1和2指定代码示例中的精度,但不是原因.为什么你需要安培和瓦特比伏特更精确?

此外,避免使用幻数允许您集中代码更改,而不必在精度需要更改时为字面数字2搜索代码.

我建议像:

HIGH_PRECISION = 3;
MED_PRECISION = 2;
LOW_PRECISION = 1;
Run Code Online (Sandbox Code Playgroud)

您的客户端代码如下所示:

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 )
Run Code Online (Sandbox Code Playgroud)

然后,如果将来你做这样的事情:

HIGH_PRECISION = 6;
MED_PRECISION = 4;
LOW_PRECISION = 2;
Run Code Online (Sandbox Code Playgroud)

你所要做的就是改变常数......

但是试着回答OP标题中的问题:

IMO唯一可以真正使用且不被认为是"魔术"的数字在迭代中使用-1,0和1,测试长度和大小以及许多数学运算.使用常量的一些示例实际上会混淆代码:

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

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

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

int MyRidiculousSignReversalFunction(int i) {return i * -1;}
Run Code Online (Sandbox Code Playgroud)

这些都是非常明显的例子.例如,开始和第一个元素并逐一递增,测试以查看集合是否为空并且标志反转......很荒谬,但作为一个例子.现在用2替换所有-1,0和1值:

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

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

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

int MyRidiculousDoublinglFunction(int i) {return i * 2;}
Run Code Online (Sandbox Code Playgroud)

现在你开始问自己:为什么我开始迭代第3个元素并互相检查?数字50的特别之处是什么?有两个元素的系列有什么特别之处?doubler示例在这里实际上是有意义的,但你可以看到2和50的非-1,0,1值立即成为魔术,因为他们正在做的事情显然有些特殊,我们不知道为什么.