半吊子
日历
网志分类
· 所有网志 (82)
站内搜索
友情链接
· 歪酷博客
· 我的歪酷 非非共享界

订阅 RSS

0069829

歪酷博客

« 上一篇: 回到起点 下一篇: 真到秋风真的北起时 »
天地间有我 @ 2007-10-06 17:37

取余大概是编程中最长使用的一种运算了,在PASCAL里面有一个关键字MOD,在C里面更简单的有一个运算符%。这个运算可以带来很多方便,稍微罗列一下:

1、在得到一个小于某数的整数
2、判定一个整数是否能被某数整除的时候
3、上一则有一个特殊的用法:判断奇偶性
4、在位BMP文件格式操作的时候,还需要计算是否需要补足位,也可能用到取余运算

这还是随便一想,当然还有很多很多别的地方也会用到了。既然这个运算如此的普遍,那我们就要考虑一下他的效率了。在前两天看CSDN的时候,有人问:n为整数时(n%10)/100与(n/100)%10谁的效率更高?其实看一眼就知道,这个命题毫无意义,因为这两个运算本身就是不等价的,不会有人因为效率问题而用其中一个运算替换另外一个。但再看一步这个问题就涉及到了取余运算在计算机里面是怎么做的这个问题了。

稍微的写一点代码,看看MS是怎么把他变成汇编的:
1:    #include <stdio.h>
2:
3:    int main(int argc, char** argv)
4:    {
0040D3F0   push        ebp
0040D3F1   mov         ebp,esp
0040D3F3   sub         esp,4Ch
0040D3F6   push        ebx
0040D3F7   push        esi
0040D3F8   push        edi
0040D3F9   lea         edi,[ebp-4Ch]
0040D3FC   mov         ecx,13h
0040D401   mov         eax,0CCCCCCCCh
0040D406   rep stos    dword ptr [edi]
5:        int     n       = 12345;
0040D408   mov         dword ptr [ebp-4],3039h
6:        int     Result1 = 0;
0040D40F   mov         dword ptr [ebp-8],0
7:        int     Result2 = 0;
0040D416   mov         dword ptr [ebp-0Ch],0
8:
9:        Result1 = ( n % 10 ) / 100;
0040D41D   mov         eax,dword ptr [ebp-4]
0040D420   cdq
0040D421   mov         ecx,0Ah
0040D426   idiv        eax,ecx
0040D428   mov         eax,edx
0040D42A   cdq
0040D42B   mov         ecx,64h
0040D430   idiv        eax,ecx
0040D432   mov         dword ptr [ebp-8],eax
10:
11:       Result2 = ( n / 100 ) % 10;
0040D435   mov         eax,dword ptr [ebp-4]
0040D438   cdq
0040D439   mov         ecx,64h
0040D43E   idiv        eax,ecx
0040D440   cdq
0040D441   mov         ecx,0Ah
0040D446   idiv        eax,ecx
0040D448   mov         dword ptr [ebp-0Ch],edx
12:
13:       return 0;
0040D44B   xor         eax,eax
14:   }
0040D44D   pop         edi
0040D44E   pop         esi
0040D44F   pop         ebx
0040D450   mov         esp,ebp
0040D452   pop         ebp
0040D453   ret

很明显,我们看到了汇编指令里面没有取余的指令,当然这个在学习汇编的时候,我们就知道的。所谓的取余是通过一个除法指令和一个移位指令组合完成的。我们知道idiv eax,ecx的整数结果是保存在eax中的,而经接着下面一句就是mov eax,edx,很明显寄存器edx里面保存的就是余数了。而这句mov dword ptr [ebp-0Ch],edx看的就更明显了,直接把余数放到变量的地址里面去了。

这样看到所谓的取余就是一个除法运算。做嵌入式系统时间一长,我也有了毛病了,一听说除法运算脑子里第一个反映出来的名次就是“慢”。

在社区里面有人提出一个问题,求一个正整数的个位数,要求程序的效率要比跟10求模效率高。

这个问题还在思考中,听说是某企业的面试题,呵呵,看来也是一家嵌入式的公司啊。



评论 / 个人网页 / 扔小纸条
* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 


 

分类小组论坛
杂谈 , 娱乐、八卦 , 文学、艺术 , 体育 , 旅游、同城 , 象牙塔 , 情感 , 时尚、生活 , 星座 , 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定