魔术数字 (程序设计)

✍ dations ◷ 2025-12-04 19:59:36 #计算机编程,反模式

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

相关

  • 拉玛尔·奥多姆拉马尔·约瑟夫·奥多姆(英语:Lamar Joseph Odom,1979年11月6日-)为美国NBA的职业篮球运动员,目前虽未发表退役声明,但因吸毒、嫖妓事件影响,亦非现役球员,场上位置司职小前锋和大前
  • 犹他爵士队犹他爵士(英语:Utah Jazz),是一支位于美国犹他州盐湖城的NBA篮球队,分属于西部的西北赛区,主场为Vivint智慧家庭体育馆。球队于1974年在新奥尔良成立,命名新奥尔良爵士(New Orleans
  • 苏城苏城(英语:Sioux City),美国艾奥瓦州西北部城市,伍德伯里县县治所在处。苏城位于密苏里河上游沿岸,地处艾奥瓦州、内布拉斯加州与南达科他州交界处,其与周遭地区经常合称为苏兰(Siou
  • 新加坡政府 政治主题在《新加坡共和国宪法》,新加坡政府是指新加坡的行政机构,由总统和内阁组成。尽管总统可自行行使职权,确保内阁和国会照常运作,不过其职责很大程度上只是礼仪性。新加
  • 葛维宝葛维宝(英语:Paul D. Gewirtz;1947年5月12日-)是耶鲁法学院波特·斯图尔特宪法学教席教授,耶鲁大学中国法律中心主任。葛维宝是他起的中文名字。葛维宝1967年毕业于哥伦比亚大学,获
  • 沈云沛沈云沛(1854年-1919年),字雨人,又字雨辰,江苏省海州直隶州(今属江苏连云港市海州区)人。清末民初政治人物。光绪二十年(1894年)甲午恩科第二甲第八十六名进士出身。同年五月,改翰林院庶
  • TWIN PLANETTWIN PLANET(日语:ツイン・プラネット)是日本的演艺经纪公司。相关企业有TWIN PLANET ENTERTAINMENT、White Base株式会社及LIDDELL株式会社。公司名称原本以首字大写写作“Twi
  • HD 60532HD 60532,又名BD-21 2007,SAO 174009、HR 2906,是一颗位于船尾座的恒星,视星等为4.45,位于银经237.5,银纬-1.19,其B1900.0坐标为赤经7h 29m 46.3s,赤纬-22° -1.19′ 48″。该恒
  • 2009年京广铁路郴州站列车相撞事故2009年京广铁路郴州站列车相撞事故又称“6·29”京广铁路特大交通事故。是2009年6月29日凌晨2:40在中国湖南省郴州市京广铁路郴州站附近发生的一起严重旅客列车相撞事故,共造
  • 高山右近参数所指定的目标页面不存在,建议更正成存在页面或直接建立下列一个页面(建立前请先搜寻是否有合适的存在页面可以取代):高山右近(1552年-1615年2月4日)是日本战国时代至江户时代初