计算机编程中的“神奇数字”是什么?

时间:2010-08-19 05:23:40

标签: language-agnostic programming-languages magic-numbers

当人们谈论在计算机编程中使用“魔术数字”时,他们的意思是什么?

11 个答案:

答案 0 :(得分:38)

魔术数字是代码中的任何数字,对于知之甚少的人来说并不是很明显。

例如,以下代码:

sz = sz + 729;

中有一个神奇的数字,写得更好:

sz = sz + CAPACITY_INCREMENT;

一些极端的观点表明你的代码中除了-1,0和1之外你不应该有任何数字,但我更喜欢一种不那么教条的观点,因为我会立刻认出24,1440,86400,3.1415,2.71828和1.414 - 它一切都取决于你的知识。

然而,即使我知道一天有1440分钟,我可能仍然使用MINS_PER_DAY标识符,因为它会搜索它们更容易。谁说上面提到的容量增量也不会是1440而你最终改变了错误的值?对于低数字尤其如此:双重使用37197的机会相对较低,将5用于多个事物的几率非常高。

使用标识符意味着您不必浏览所有700个源文件,并在容量增量更改时将729更改为730。你可以改变一行:

#define CAPACITY_INCREMENT 729

为:

#define CAPACITY_INCREMENT 730

并重新编译该批次。


将这与魔术常数进行对比,这是因为天真的人认为只是因为他们从代码中删除了实际的数字,他们可以改变:

x = x + 4;

为:

#define FOUR 4
x = x + FOUR;

这会为您的代码添加绝对的额外信息,这完全是浪费时间。

答案 1 :(得分:6)

“幻数”是出现在

等语句中的数字
if days == 365

假设你不知道一年中有365天,你会发现这句话毫无意义。因此,将所有“魔术”数字(在程序中具有某种重要性的数字)分配给常量是一种很好的做法,

DAYS_IN_A_YEAR = 365

从那以后,与之相比。它更容易阅读,如果地球被排除在外,并且我们获得了额外的一天......你可以轻松地改变它(其他数字可能更有可能改变)。

答案 2 :(得分:5)

有多个含义。大多数答案已经给出的(一个任意未命名的数字)是一个非常普遍的答案,我唯一要说的就是有些人走向定义的极端......

#define ZERO 0
#define ONE 1

如果你这样做,我会追捕你,毫不留情。

但是,另一种幻数用于文件格式。它只是一个值,通常是文件中的第一件事,它有助于识别文件格式,文件格式的版本和/或特定文件的字节序。

例如,您可能有一个幻数0x12345678。如果你看到这个神奇的数字,那么你可以看到一个正确格式的文件。另一方面,如果您看到0x78563412,那么您可能会看到相同文件格式的字节序交换版本。

“魔术数字”这个术语有点被滥用,但几乎所有标识文件格式的东西都被滥用 - 包括标题中相当长的ASCII字符串。

http://en.wikipedia.org/wiki/File_format#Magic_number

答案 3 :(得分:4)

维基百科是您的朋友(Magic Number文章)

答案 4 :(得分:3)

到目前为止,大多数答案都将幻数描述为一个非自我描述的常数。作为一个“老派”程序员自己,回到那一天我们将魔术数字描述为任何常量,这些常量被分配了一些影响代码行为的特殊目的。例如,数字999999或MAX_INT或其他完全任意的。

魔术数字的一个大问题是它们的目的很容易被遗忘,或者在另一个完全合理的语境中使用它的价值。

作为一个粗暴而极其人为的例子:

while (int i != 99999)
{
  DoSomeCleverCalculationBasedOnTheValueOf(i);      

  if (escapeConditionReached)
  {
    i = 99999;
  }
}

使用或不命名常量的事实并不是真正的问题。在我可怕的例子中,值会影响行为,但是如果我们需要在循环时更改“i”的值呢?

显然,在上面的例子中,你不需要一个幻数来退出循环。你可以用break语句替换它,这是魔术数字的真正问题,它们是一种懒惰的编码方法,并且总是可以被不太容易失败的东西所取代,或者随着时间的推移失去意义。

答案 5 :(得分:2)

除了应用程序本身之外,任何对任何人都没有明显意义的东西。

if (foo == 3) {
    // do something
} else if (foo == 4) {
    // delete all users
}

答案 6 :(得分:2)

幻数是某些变量的特殊值,会导致程序以特殊方式运行。

例如,通信库可能会采用Timeout参数,并且可以定义幻数“-1”以指示无限超时。

答案 7 :(得分:1)

术语幻数通常用于描述代码中的某些数字常量。出现的数字没有任何进一步的描述,因此其含义是深奥的。

使用命名常量可以避免使用幻数。

答案 8 :(得分:0)

在0或1以外的计算中使用未由某些标识符或变量定义的数字(这不仅可以通过在一个地方更改数字而在几个地方轻松更改,还可以使读者清楚这个数字是多少)。

答案 9 :(得分:0)

简单而真实的单词中,幻数是三位数,前两位的平方和等于第三位。 EX-202, as,2 * 2 + 0 * 0 = 2 * 2。 现在,java中的WAP接受一个整数并打印是否是一个幻数。

答案 10 :(得分:0)

它可能看起来有点平庸,但每种编程语言至少有一个真正的神奇数字。

0

我认为,在几乎所有程序员的魔杖颤抖中统治它们都是神奇的魔杖。

FALSE不可避免地为0 TRUE不是(FALSE),但不一定是1!可以是-1(0xFFFF)

NULL不可避免地为0(指针) 并且大多数编译器允许它,除非他们的类型检查是彻头彻尾的狂热。

0是数组元素的基本索引,除非语言过于陈旧,基本索引为“1”。然后可以方便地编码(i = 0; i< 32; i ++),并期望'i'将从基数(0)开始,并且增加到,并且停止在32-1 ...第32个成员一个数组,或其他什么。

0是许多编程语言字符串的结尾。 “停在这里”的价值 0同样内置于X86指令中以“有效地移动字符串”。节省许多微秒。

程序员经常使用

0表示例程执行中“没有出错”。它是“非例外”代码值。可以使用它来表示缺少抛出异常。

零是程序员最经常给出的做一些完全无关紧要的工作量的答案,比如将活动单元格的颜色改为紫色而不是亮粉色。 “零,伙计,就像零!”

0是我们希望实现的程序中的错误计数。 0个未解释的例外,0个未终止的循环,0个无法实际获取的递归路径。 0是我们试图在编程劳动,女朋友(或男朋友)“问题”,糟糕的餐厅体验和一个人的汽车的一般特质方面实现的渐近线。

是的,0确实是一个神奇的数字。远比任何其他价值更具魔力。没什么......唉,接近了。

rlynch@datalyser.com