魔术数字 (程序设计)

✍ dations ◷ 2025-05-20 14:35:23 #计算机编程,反模式

程序设计中所谓的魔术数字(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)这两种字符串。

相关

  • 祝由十三科祝由十三科,又称祝由科、祝由术,是古代医术的流派,即“祝说病由”,不需用针灸或药来治病。祝由科,自元代即列入太医院十三科。祝由二字,最早见于医书《素问》,谓上古之人治病,不用打
  • 海涅克里斯蒂安·约翰·海因里希·海涅(德语:Christian Johann Heinrich Heine,1797年12月13日-1856年2月17日),出生时用名哈里·海涅(Harry Heine),19世纪最重要的德国诗人和新闻工作者
  • 蟾酥蟾酥,亦称蟾毒素,是中药材攻毒杀虫止痒药的一种,该药材出自于《药性论》一书,有解毒止痛的功效。蟾酥为蟾蜍科动物中华大蟾蜍(Bufo gargarizans Cantor)或黑眶蟾蜍(Duttaphrynus me
  • 公地放领公地放领系公地管理机关及县(市)政府依据法令规定之实体与程序,准许符合规定之承租农民依照规定程序申请承领,于缴清全部放领地价后,移转土地所有权之私法上分期付款之买卖行为,其
  • 拉森拉森国家森林(英语:Lassen National Forest)是一座美国国家森林,位于加利福尼亚州东北部,占地面积1,700平方英里(4,400平方千米),名自1850年代,将此地开采、耕作,并向移居而来的人们推
  • 陆军装甲兵学院中国人民解放军陆军装甲兵学院,简称陆军装甲兵学院,本部位于北京市丰台区,隶属中国人民解放军陆军,是培养装甲兵指挥、参谋、技术保障军官和指挥管理、维修保障士官的综合性高等
  • 我心狂野《我心狂野》(Wild at Heart)是1990年的美国黑色幽默爱情犯罪片,由大卫·林奇担任编剧及导演,由尼古拉斯·凯奇、劳拉·邓恩、黛安·拉德、威廉·达佛、哈里·迪恩·斯坦顿及伊
  • 佛科留斯系统佛科留斯系统(Galaxy morphological classification)被视为是哈伯序列的扩充,并被广泛的使用者,最早是在1959年由热拉尔·佛科留斯 (Gérard de Vaucouleurs)提出的。佛科留斯认
  • 石隆门华工起义布鲁克王朝同盟军队:石隆门华工起义(1857年)是一起当地华人矿业公司因不满砂拉越布鲁克王朝的政策而发动的起义事件。十二公司为帽山华人矿工组织,首领为刘善邦。以开发帽山、石
  • 肖普号驱逐舰肖普号驱逐舰(USS Shoup (DDG-86))是美国海军阿利·伯克级驱逐舰的第三十六艘,以海军陆战队上将戴维·M·肖普命名。肖普号驱逐舰于1999年12月13日在密西西比州帕斯卡古拉的英