首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

快速算法

2012-03-21 
求一个快速算法:给一个二进制串,如何判断是否为10的幂的倍数?下面的代码摘自帖子:http://community.csdn.n

求一个快速算法:


给一个二进制串,如何判断是否为10的幂的倍数?    


下面的代码摘自帖子:

http://community.csdn.net/Expert/topic/5694/5694226.xml?temp=.3801538#top

直接使用%10统计判断了10到1000000的count数字,

希望找到一个比她快的算法。


[解决办法]
to shshsh_0510(雨下了4年11个月零2天):
你在“超难VS基础: 如何快速判断10的倍数?”提到:

inline BOOL testDivisibility10_lbc5( const UINT32 u32Num )
mov eax, u32Num;
mov edx, 0xCCCCCCCD;
mul edx;
显然mov edx, 0xCCCCCCCD;这句可以省去,变为
mov eax, u32Num;
mul 0xCCCCCCCD;
从而减少一个clock.但是,根本看不到什么效果。”


关于这个问题,我和gxq在 “千分求汇编优化:UInt96x96To192(...)”已经讨论过,下面将相关内容摘录如下:

我的回复:
我和楼主的不同做法之一是:
我在作乘法时,用了3条指令(见下),楼主一般用2条指令。
mov eax,dword ptr [esi+ 8]
mov edx,dword ptr [edi+ 4]
mul edx
由于: “ mov eax,dword ptr [esi+ 8]”和“ mov edx,dword ptr [edi+ 4]”是非相关指令,可同时执行,因此他不会比 “ mov eax,dword ptr [esi+ 8],mul dword ptr [edi+ 4] "更慢。”


gxq给出的测试代码片断:
#ifdef _MUL_REG
mov edx, dword ptr[esi + 0x08];
mul edx; // L2*R2
#else
mul dword ptr[esi + 0x08];
#endif


gxq给出的测试结果:

试耗时(单位:ms) A B C1 C2
UInt96x96To192: 6359 6100 3328 671
UInt96x96To192_2: 4437 5270 3281 640
UINT96x96To192SSE2: 6062 不支持 4110 ---
UInt96x96To192_ALU: 4609 7250 4219 875
UInt96x96To192_ALU_v2: 4796 5380 2516 531
UInt96x96To192_ALU_v3: 3890 4890 2375 500
UInt96x96To192_ALU_v3_MulReg: 4000 5160 2422 500

A、WinXP SP2 / PIV 2.93 / VC++6.0 + ICC 9.1 / 测试1亿次
B、Win98Sec / Intel Celeron 466MHz / VC++6.0 / 测试2千万次
C1、WinXP SP2 / AMD Athlon(tm) 64 3200+, 2.01 GHz / 在机台A上编译的程序
C2、WinXP SP2 / AMD Athlon(tm) 64 3200+, 2.01 GHz / 在机台B上编译的程序

测试结果表明:
1、用纯 ALU 指令,当前的最优版本为 UInt96x96To192_ALU_v3(..);
2、mul reg 并非为最佳选择,尤其当这个 reg 值以后不被复用时;
3、用纯 ALU 指令优化似乎已接近尽头,期待 SSE2 优化版本的出现。。。


我的观点::
从上述测试数据可以看出,这两种方法确实相差很小,A,B,C1三台机器中,少一条指令的版本仅比通常的版本快2.8%,5.5%,1.9%,可以认为速度相同。



[解决办法]
你的题目说二进制串 ,但是你写的不啊
[解决办法]
今天自己看了下说的是二进制度串,怎么测试的时候都是10进制项啊,要是都是10进制那还比个P啊,直接看最后一位就行了。
[解决办法]
可以提供一个方法,效率不做保证。

设n为输入值。

1): v=n+1; v+=|_v/2_|;
2): v+=|_v/16_|; v+=|_v/256_|; v+=|_v/65536_|; ... ; v+=|_v/(2^(2^k))_|;
[ 此过程直至增量|_v/(2^(2^k))_|为0时停止 ]
3): q=v/16;
4): r=v%16; r+=|_r/4_|; r=|_r/2_|;

经过上面的步骤,q近似等于n除以10的商,r则近似等于余数。
令M=2^(2^(k+1));之所以是“近似”,是因为:当n> =M/2+4时上面的算法可能出错。
比如:n=132。

上面算法的4),可以改进如下:

4):r=n-8*q; r=r-2*q;

[解决办法]
任何运算都比不过位移运算,那哥们汇编和计算机组成原理的理论很深。
[解决办法]
学习
[解决办法]
学习,呵呵
楼上的果然厉害

热点排行