算法中会出现magic number的原因:1、经验所得;2、代码多次计算;3、缺少宏定义或常量;4、代码重构不彻底。经验所得是指一段代码经过多次测验,发现某个数字可以在某种情况下最接近你最想要的结果,那么这个数字就会变成magic number。
一、算法中会出现magic number的原因
1、经验所得
经验所得是指一段代码经过多次测验,发现某个数字可以在某种情况下最接近你最想要的结果,那么这个数字就会变成magic number。例子:如果平常随机种子都用时间戳,但突然用一个特定的数字做随机种子,往往随机出来的结果都比较好。
2、代码多次计算
代码在多次计算后,得出一个结果用于最终程序。例如一个展开式中的某个系数,用于某迭代过程;或者是在预处理过程中得出的结果直接使用到最终程序中等等。例子:quake3中的sqrt。
3、缺少宏定义或常量
在修改代码时,可能会忽略一些常量的值,特别是嵌套深度很深的条件语句中的常量,导致代码中存在未被修改的“Magic Numbers”。
4、代码重构不彻底
在编写代码时,可能会缺乏合适的宏定义或常量,这可能导致在代码中使用硬编码的数字(“Magic Numbers”)。
二、magic number简介
魔术数字(magic number)是程式设计中所谓的直接写在程式码里的具体数值(如“10”“123”等以数字直接写出的值)。虽然程式作者写的时候自己能了解数值的意义,但对其他程式员而言,甚至制作者本人经过一段时间后,会难以了解这个数值的用途,只能苦笑讽刺“这个数值的意义虽然不懂,不过至少程式会动,真是个魔术般的数字”而得名。
所谓魔数和魔字符串就是指在代码中出现但没有解释的数字常量或字符串,又称魔法值。如果在某个程序中你使用了魔数,那么在几个月或几年后你将很可能不知道它的含义是什么。大多数情况下,我们都是通过扩展名来识别一个文件的类型的,比如我们看到一个.txt类型的文件我们就知道他是一个纯文本文件。但是,扩展名是可以修改的,当一个文件的扩展名被修改过,识别一个文件的类型就用到了我们提到的“魔数”。很多类型的文件,其起始的几个字节的内容是固定的(或是有意填充,或是本就如此)这几个字节的内容也被称为魔数,因为根据这几个字节的内容就可以确定文件类型。有了这些魔术数字,我们就可以很方便的区别不同的文件。
三、magic number分类
1、有害的magic number
指的是代码中出现的没有说明的数字。代码中突然出现一个没说明用途的数字会让其它阅读代码、维护代码的的人非常难受。例如:
const int N = 2073600;
for (int i=0; i<N; i++)
{ ......
看代码的人需要猜2073600是什么意思,而且特别难猜。改成这样就清楚多了:
const int WIDTH = 1920;
const int HEIGHT = 1080;
int totalPixels = WIDTH * HEIGHT;
这里的“魔数”就是指代码中直接出现的数字。现代编程规范比较忌讳这样写代码,一方面看不懂意思,另一方面如果2073600这个数字多次出现,一旦需要修改的时候就需要全部找出来改掉,一旦少改一处就会产生BUG,非常麻烦。我们在编程中要尽可能避免使用“魔数”,例如写3.1416这种数字,也应该改为数学库中的π常数,例如Unity中的Mathf.PI。
2、有益的magic number
最典型的例子就是现代3D游戏之父约翰·卡马克在雷神之锤中的那个魔数:
i = 0x5f3759df - ( i >> 1 );
配合前后的代码,这句代码可以快速计算一个数字的平方根的倒数。具体推导过程比较复杂,涉及到浮点数的原理。这个操作给了其它人非常大的震撼,是那个年代的大神级编程技术的缩影,所以被人们怀着敬仰之情称之为“魔数”,全称为“如魔法一样神奇的数字”。
3、一般的magic number
某些具有特定格式的文件,喜欢在文件开头写几个特殊的字符以表明自己的身份,以便验明正身。例如常见的几种图片格式的文件:
- JPEG (jpg),文件头:FFD8FF
- PNG (png),文件头:89504E47
- GIF (gif),文件头:47494638
- Windows Bitmap (bmp),文件头:424D
如果你用16进制编辑器打开一个文件,它的开头不是FFD8FF,那就不是jpg文件。这个魔数一般会在相关文件标准中进行规定,所有人都要遵守。
延伸阅读
如何避免magic number
为避免因“Magic Number”造成的问题,可以通过引入常量、枚举及其他宏定义等方式来减少硬编码的数字的使用,使代码更加灵活、易读和维护。同时,还可以通过编写注释来解释“Magic Number”的含义,从而帮助开发人员更好地理解它们的作用。
文章标题:为什么算法中会出现magic number,发布者:Z, ZLW,转载请注明出处:https://worktile.com/kb/p/49370