魔术数字 (程序设计)

✍ dations ◷ 2025-11-24 22:09:58 #计算机编程,反模式

程序设计中所谓的魔术数字(magic number)可能有以下含意:

魔术数字可以是指硬编码在代码里的具体数值(如“10”“123”等以数字直接写出的值)。虽然程序作者写的时候自己能了解数值的意义,但对其他程序员而言,甚至制作者本人经过一段时间后,会难以了解这个数值的用途,只能苦笑讽刺“这个数值的意义虽然不懂,不过至少程序能够运行,真是个魔术般的数字”而得名(起源参考平方根倒数速算法)。

因为下述理由,一般认为代码中不应该含有魔术数字。

例1:

price_tax = 1.05 * price

例1是对输入的价格(price)计算含税(price_tax)售价的程序。但税率并不是万年不变,当政府调整税率时,会有修改程序的必要。这里“1.05”就是一种魔术数字,“为什么是1.05”会让人无法马上了解。下面是去掉魔术数字的示例,程序容易了解也容易修正。

例1 (修正):

TAX = 0.05price_tax = (1.0 + TAX) * price

例2:

setColor("text", 0xffffff)

例2是设置以白色显示代码。然而十六进制的色码0xffffff很难直觉看懂是“白色”,故也算是一种魔术数字。下面是一种拿掉魔术数字的方式。

例2 (修正):

white = 0xffffffsetColor("text", white)

像这样,将魔术数字置换成常量或枚举类型是经常用来解决魔术数字问题的手段。由于常量可以赋予易懂的名称,可使帮助阅读者了解数值的意义。当然,在程序初始化部分定义的常量列表不称为魔术数字。

例3:

year = (new Date()).getYear() - 1911;

例3是用来获取今年之民国纪年的代码。然而将“1911”硬编码在代码里并不尽理想,例如程序不易在其他国家使用等。下面是一种拿掉魔术数字的方式。

function getMinguoYear() { return (new Date()).getYear() - 1911; }year = getMinguoYear();

这个示例则使用函数来包装整段计算民国纪年的逻辑,函数内则直接保留数值1911。这样做的好处是在程序中可借由getMinguoYear()这个函数名称更容易了解程序意图,并对未来若需支持其他国家时保留弹性。例如,需要使用日本历时,可只抽换函数部分而不动到程序所有参考年份运算的地方。

另外,在 一些编程语言中,1与0经常直接作为“真”、“假”的意义(布尔值)使用,有时候也不被认为是魔术数字。(但近年的语言多半建议使用与替代。)

魔术数字也会在文件中使用。在特定文件格式中加入固定数值和固定字符串,然后便可以通过检查文件是否包含这些数据来快速地识别文件格式。

例如:GIF文件开头会包含GIF89a47 49 46 38 39 61)或GIF87a47 49 46 38 37 61)这两种字符串。

相关

  • 菲律宾海板块隐没带 Alps 造山带 30→ 相对于非洲板块的移动速度(mm/Y)菲律宾海板块(英语:Philippine Sea Plate),是位于西太平洋菲律宾海的一个大洋板块,其形状略呈菱形,面积在30个主要板块中排
  • 弗拉基米尔·阿诺尔德弗拉基米尔·伊戈列维奇·阿诺尔德(俄语:Влади́мир И́горевич Арно́льд,1937年6月12日-2010年6月3日),俄国数学家,生于苏联敖德萨(今乌克兰境内)。1957年
  • 华盛顿纪念碑华盛顿纪念碑(英语:Washington Monument),是美国首都华盛顿哥伦比亚特区的地标,为纪念美国总统乔治·华盛顿而建造,石碑建筑物的内部中空,是世界最高的石制建筑,原本米尔斯的最初设
  • 终身成就奖终身成就奖是一种由组织授予、表彰个人在整个生涯中对该领域的整体贡献,而不是单一的成就。授予这个奖项的组织如下:福布斯终身成就奖
  • 价川市价川市(朝鲜语:개천시/价川市 Kaechŏn si */?)位于朝鲜平安南道,其地理坐标为39°41′55″N 125°54′22″E / 39.69861°N 125.90611°E / 39.69861; 125.90611。水利资源较
  • 威廉·布劳威廉·扬松·布劳(荷兰语:Willem Janszoon Blaeu,1571年-1638年),文艺复兴时期欧洲荷兰地理学家与出版家。曾随丹麦天文学家第谷从事研究工作。他制有地球仪和地图册,并于1605年出
  • 陶钰玉陶钰玉(1988年8月25日-),中国大陆流行音乐女歌手。她曾是中国大陆三人女子歌唱组合T.R.Y中的一员,2007年该组合曾经因薪酬原因一度解散,之后陶钰玉便留在孔雀唱片公司单独发展。
  • 动态调度在计算机科学中,动态调度(Dynamic dispatch)是指运行时选择哪一个多态操作的实现(方法或函数)来调用的过程。动态调度通常被应用于面向对象编程(OOP)的语言和系统,并被认为是一个主
  • 巴耳末公式巴耳末公式是1885年由瑞士数学教师巴耳末提出的用于表示氢原子谱线波长的经验公式其中λ是谱线的波长,B=3.6546×10-7m。,是一个常数。巴耳末公式的提出经历了一个曲折的过程
  • 孙燧 (弘治进士)清代修《浙江余姚孙氏宗谱》之忠烈公像孙燧(1460年-1519年),字德成,号一川,浙江余姚县人。家族出于横河孙氏,明朝忠臣。官至江西巡抚,宁王朱宸濠谋反时将其杀害。身后追赠礼部尚书,谥