会变语言实现的一些程序
源代码在线查看: 超长的进制转换 .txt
超长的进制转换
作者:Jean 于2008-6-16上传
--------------------------------------------------------------------------------
当十六进制看着不方便的时候,就需要将其转换成十进制。基本算法就是把这个十六进
制数除以10(十进制10,十六进制A),余数占十进制整数的最低位,这样继续下去,可以算出十进制数的次低位等等,
直到被除数小于10为止。
比如,把十六进制数 1234H 转换成十进制数过程如下:
被除数 商 余数
1234 1D2 0
1D2 2E 6
2E 4 6
4
总共进行了3次除法,余数按先后顺序排列为0 6 6 4,由于余数在0-9范围之内,合并余数组成十进制数4660。所以,
1234H的十进制表示就是4660。
利用FPU的指令FBLD FBSTP可以简化运算。FBLD指令可以加载内存中的一个10字节长度(最高字节是符号字节)的压缩BCD码
(也就是十进制数),FBSTP可以将ST0寄存器中的数转保存成一个长10字节的压缩BCD码。
例如,将11111111转换成一个DWORD型的16进制数:
BCD DB 11 11 11 11 00 00 00 00 00 00
MOV ESI,OFFSET BCD
FBLD [ESI]
FISTP DWORD PTR [EDI]
现在考虑将一个长度任意的16进制数转换成10进制数。首先,它转换成10进制后长度是多少?
这里我只给出算法,设Lh,Ld分别是16,10进制数的长度:
16^Lh~=10^Ld =>
Ld/Lh~=log(16)/log(10)~=1.205
Lh/Ld~=log(10)/log(16)~=0.835
30K的16进制数转换成10进制数长度估计为30000*LOG(16)~=36124字节.
算算误差,两种极端情况,当16进制数最大(ffff...),10进制数最小(1000...)时,有下面的式子
16^(Lh+1)-1=10^Ld 记这里的Ld为Ldmax
相反地,当16进制数(1000...)最小,10进制数(9999...)最大时,有:
16^Lh=10^(Ld+1)-1 记这里的Ld为Ldmin
当数的长度增加时,LH/LD会趋于1/LOG(16),当数很小时,LH/LD会偏离1/LOG(16)。
现在看看转换成10进制数后长度变化范围最大最小有多大:
delta=Ldmax-Ldmin=log(16-17/(16^Lh+1))+1,Lh>=1.
=> 2.176 < delta < 2.205
因此,在给结果分配内存空间时,多分配2个字节,保证给足。30K就分配30K*LOG(16)+2=36126个字节。
同样地,当是10进制数时候,将其转成16进制数,数长约为N/LOG(16)+2个字节。
用先前介绍的方法,做将一个任意长度的数在16 10进制之间互相转换,见例子程序,仅做参考。
[Z.t注]:附件conversion.txt是一个十六进制数,运行sample后,即转化这个数为十进制,结果是
很大的一个数,88888....88。
--------------------------------------------------------------------------------
欢迎访问AoGo汇编小站:http://www.aogosoft.com 下一篇>>>