魔术数字 (程序设计)

✍ dations ◷ 2025-07-27 18:23:47 #计算机编程,反模式

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

相关

  • 固态瘤新生物、息肉、瘜肉或赘生物(英语:neoplasm),是指身体细胞组织不正常的增生,当生长的数量庞大,便会成为肿瘤(英语:tumor)。而肿瘤亦可以是良性或恶性的。肿瘤(英语:tumor)在医学上是指细
  • 米氏动力学米-门二氏动力学(英语:Michaelis-Menten kinetics),又称米氏动力学,是由雷昂诺·米凯利斯(英语:Leonor Michaelis)和贸特·门顿(英语:Maud Menten)在1913年提出,它在酶动力学中是一个极
  • 首位城市首位城市(英语:primate city)是指在一个国家或地区的城市等级体系中,规模最大且不成比例地大于其他城市的城市。这一概念于1939年由地理学家马克·杰佛森(M.Jefferson)在《城市首位
  • 鱼素者鱼素主义(Pescetarianism)是指戒食红肉、禽类肉食,但仍进食海鲜(以鱼为主)的饮食习惯。鱼素者对各类型病菌、禽流感等疾病、肥胖、过敏等健康方面的担忧,因而放弃红白肉,改以鱼类来
  • 障子障子(しょうじ),是一种在日式房屋之中作为隔间使用的可拉式糊纸木制窗门。在公寓的和室之中,障子也被与玻璃窗搭配使用以取代窗帘。虽然该种窗门在现代日本已逐渐少见,但在日式旅
  • 架空历史小说架空历史小说(英语:Alternate history、alternative reality,简称架空小说),即描述“并非真实发生的虚构历史”的小说,包括历史背景及未来。小说的最大不同在于故事通常会发生在一
  • 总已知重量总已知重量 (Total known weight,TKW) 这个名词主要是陨石收藏家和经销商用于陈述在单一陨石名称下所有已知碎片的总重量 ,而总已知质量只是被命名的陨石进入大气层之前原始总
  • 宋雅王后国王陛下 王后陛下阿斯特丽公主殿下宋雅王后(挪威语:Sonja av Norge,1937年7月4日-)名宋雅·哈拉尔森(Sonja Haraldsen)生于 奥斯陆的红十字诊所(Red Cross Clinic),挪威国王哈拉尔
  • 储家昌储家昌(1913年-2009年12月12日),字正平。江苏省如皋县人。民国37年(1948年)在江苏省第四选区当选第一届立法委员
  • 偏穗草科偏穗草科包括17属约80余种,分布在热带的南美洲东部和非洲西部。1981年的克朗奎斯特分类法将其列入鸭跖草目,1998年根据基因亲缘关系分类的APG 分类法认为无法将其列入任何一目