超长的进制转换
相关的例子:下载>>> 作者: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
下一篇>>>