魔术数字 (程序设计)

✍ dations ◷ 2025-09-07 20:16:41 #计算机编程,反模式

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

相关

  • 高胆固醇血症高胆固醇血症(Hypercholesterolemia)是指血液中的胆固醇偏高的情形。高胆固醇血症属于高脂血症及高脂蛋白血症(hyperlipoproteinemia,血液中脂蛋白过高的病症)。血液中非高密度脂
  • 库兹涅佐夫号航空母舰库兹涅佐夫号航空母舰是俄罗斯现役最新型的航空母舰,在苏联时期建造,苏俄计划号码为1143.5号计划重型航空巡洋舰,于1983年开工建造。该舰建造时期原名苏联号、克里姆林宫号、布
  • 雅各布·帕里斯雅各布·帕里斯(葡萄牙语:Jacob Palis,1940年3月15日-),巴西数学家。2013年当选为中国科学院外籍院士。
  • 毒气毒气(又称“有毒气体”或“剧毒气体”,旧称“毒气瓦斯”或“毒瓦斯”)乃气态的毒素,是对生物体有害的气体之统称。一般而言是攻击或毁损呼吸道,造成窒息或肺出血的病症。吸入过量
  • 毕比·诺维尔什毕比·诺维尔什(英语:Beatrice "Bebe" Neuwirth,1958年12月31日-),为著名的美国女演员、歌手和舞者,在美剧《欢乐酒店》中饰演Dr. Lilith Sternin一角而出名,另外,她参与演出的芭蕾舞
  • 怒苏语怒苏语是怒族使用的语言之一,属于藏缅语族彝语支,主要分布在云南省怒江傈僳族自治州的泸水、福贡等县。约有9000人使用。有3个方言。方言间通话困难。音节结构简单,以开音节为
  • 全欧网络全欧网络(英语:Trans-European Networks)是欧洲联盟为落实及开发共同市场、并加快联盟的社会及经济一体化进程而拟定的一项方针。其重点计划在于改进共同市场的交联,并对部分运
  • 长鳍金枪鱼长鳍金枪鱼(学名:Thunnus alalunga)是金枪鱼的一种,可以食用,因胸鳍很长——约为体长的30%而得名,生活在全球热带和温带海洋及地中海,为外洋性鱼类,会洄游,肉食性,以小鱼及乌贼为食。
  • DDR SDRAM双倍数据率同步动态随机存取存储器(英语:Double Data Rate Synchronous Dynamic Random Access Memory,简称DDR SDRAM)为具有双倍数据传输率(英语:Double data rate)的SDRAM,其数据
  • 中部森林管理局中部森林管理局(日语:中部森林管理局/ちゅうぶしんりんかんりきょく )是日本林野厅在长野县长野市的地方支分部局,管辖范围为长野县、富山县、岐阜县和爱知县。另外,静冈县受关东