Panic的小屋

国破山河在,城春草木深。
随笔 - 151, 评论 - 1314, 引用 - 22, 文章 - 0

导航

公告

<2008年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

留言簿(251)

随笔分类

随笔档案

文章档案

相册

国外好站推荐

工具网页

我的其他网页

我的网友

户外运动

美女的空间

搜索

最新评论

阅读排行榜

评论排行榜

浅析Magic Number

Posted on 2006-01-21 11:35 Panic 阅读(6084) 评论(13)  编辑 收藏

浅析Magic Number


作者: Panic 2006年1月21日

什么是magic number?先看看wiki给的定义:

In computer programming, a magic number is a special constant used for some specific purpose. It is called magic because its value or presence is inexplicable without some additional knowledge.

基本含义就是,一个不能提供任何额外信息的数字。而我个人更倾向下面这种定义,尽管两者在语义上是极其相似的:

A number appearing in a program whose appearance tells you nothing about its intended purpose or meaning.


magic number的翻译一般是“幻数”或者“魔数”,magic是一个充满神秘色彩的单词,表达神秘,未知等复杂的寓意,而这也正是magic number在代码中的所作所为:当你看到它时,会感到“莫名其妙”。

因此,判定一个数字是否是magic number的依据,是它的出现是否能提供足够的信息让你理解其所指代的行为和场景。


看下面的代码行:

s = 10.0 * t * t / 2.0;

这里面包含了两个数字,在这种情况,这两个数字都是magic number,因为无法从这两个数字推断出任何额外的信息。

这行代码其实是表达下面的含义:

const double g = 10.0; //用10.0作为重力加速度g = 9.8的近似值。
s = g * t * t / 2.0;

代码改成这样,我们消除了一个magic number,那么另一个呢?

另一个已经不是magic number了,因为,众所周知,这行代码其实是理想自由落体掉落的距离/时间公式,公式中的 /2.0无法用更明确的单词来表达,所以,它不是magic number。


再看一个例子:

s = 3.14159 * d;

相信很多人都能猜得到,这是根据直径计算圆周长的公式,式中3.14159是圆周率PI的近似值。一般的,用一个PI或者MATH_PI来表达是更友好的形式:

s = PI * d;

但是,即使这样,也有例外的情况:在工程计算中,有时候明确规定了计算中对PI取值的精度,例如:保留小数点后两位数字(3.14)。

这时候,如果按照上面的例子,我们需要做类似这样的定义:

const double pi_with_two_decimal_digits = 3.14; //计算中使用的PI只保留两位小数。当然,或许你有更简洁的定义方式。
s = pi_with_two_decimal_digits * d;

毫无疑问这样一来代码更复杂了,可读性并不见得有所改善。因此,这时候使用3.14作为替代品,可以认为不是一个magic number。


magic number有几个特例:

一个特例是C++中,指针初始化为0值,类似这样:

int * p = 0;

0本身并不能准确表达一个“空指针”或者类似的含义(因为缺乏类型信息),但是,在借助了语法的规定和上下文场景之后,这种表达得以实现,所以0在这种场合不是magic number。


第二个是循环变量初始化为0:

for( i = 0;//....

作为已经被广泛接受的初始化方式,也没有必要写成for( i = loop_start;或者其他形式。而在STL则使用更富含义的it = container.begin()


第三个是 ~0 或者 -1

多数情况, ~0 或 -1 用来表示某类型的每个bit都是1的数字,这种表示方法一般不受类型本身长度限制(如果写成0xFFFF就只能用在short或者更短的类型)。

这时候0和 -1 也不认为是magic number。


实际编程中,0,1和-1作为非magic number出现的频率极高,而其他数字则多数是magic number,因此不少的书籍和资料都推荐0,1,-1或其中的某几个之外的其他数字都作为magic number。但是要注意这是一个建议而非原则。

 

magic number的界定其实是个模糊的概念,因为对于特定的数字表达,不同领域的人的认识是不同的。

例如7.91,对于多数人来说是个magic number,但是对天文/航天领域来说它就是大名鼎鼎的第一宇宙速度。在这个领域中使用这个数值一般不会带来疑问,也就不能成为magic number。

而用来表达第一宇宙速度的常数名V1,反而更容易引起误解,尤其是对其他领域的人来说。


最后,magic number是关系代码可读性/可理解的元素,与其同时存在还有magic string,magic variable等等其他充满"magic"的元素,代码中需要消除的不仅仅是magic number。

Feedback

# re: 浅析Magic Number

2006-01-21 21:28 by 一笑
中心思想不明,没看懂想说啥~

# re: 一笑

2006-01-21 21:32 by panic
是啊,我也不知道中心思想,不过只是想说明一点,magic number是和具体的数值无关的,多数时候只取决于这个数字是否能有效表达程序的逻辑。

# re: 浅析Magic Number

2006-01-22 12:06 by 清风雨
蛮好!—— 关于代码可读性的一个详细方面的建议和说法。

# re: 浅析Magic Number

2006-01-23 09:10 by 小明
说得不错!

但是C/C++里面的常量经常用宏来表示,宏的值可以被用户改变,这一点比较不好。


# re: 浅析Magic Number

2006-02-01 02:47 by euclid
常识吧……

# re: 浅析Magic Number

2006-03-26 00:43 by shanzy
文章不错,

# re: 浅析Magic Number

2007-07-01 12:27 by longlife
magic number n. 1.【核】幻数(使原子核呈高度稳定状态的质子和中子数:2, 8, 20, 28, 50, 82 和 126)2.【棒】魔机数(某赛季中预测确保领先队稳夺冠军的胜场数)

# re: 浅析Magic Number

2007-07-01 12:31 by longlife
magic number n. 1.【核】幻数(使原子核呈高度稳定状态的质子和中子数:2, 8, 20, 28, 50, 82 和 126)2.【棒】魔机数(某赛季中预测确保领先队稳夺冠军的胜场数)

# re: 浅析Magic Number

2007-08-03 14:24 by badwei
看着觉得没有中心思想的人,去恶补基础吧

# ousrovex

2007-08-28 23:43 by ousrovex
 <a href="http://dwjljsti.com">miuvkjwu</a>  [URL=http://vcnvubxq.com]bsdgucpw[/URL]  xywmijcc http://pxopketp.com kwloaije ztkronnk 

# ckikqewn

2007-08-29 02:31 by ckikqewn
 <a href="http://ypuyklss.com">mywirgfh</a>  [URL=http://vbmhswut.com]etgqsqqr[/URL]  eboorovb http://mjdcsovi.com wxvieuev uauqebzv 

# re: 浅析Magic Number

2007-09-11 09:37 by LOVE
HOW ARE YOU!
   请问在哪里申请MSN号码的, 
                                     谢谢!

# re: 浅析Magic Number

2008-09-03 00:31 by Raywill
其实对MagicNumber的精髓没有点到。
请看:
http://blog.csdn.net/maray/archive/2008/08/23/2816802.aspx
标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]