进制转换

*===================================================================================
*作 用:2-36进制的转换
*语 法:Base_Convert(cNumber,nFromBase,nToBase)
*参数说明:cNumber 要转换的字符型值,nFromBase 原进制,nToBase 目标进制
*返 回 值:字符串,错误返回空串
*BY:整数部分(xuzuning(唠叨) 、清风) 小数部分(十豆三)
*说明
*本函数将数字符字串 cNumber 从以 nFromBase 进位转换到以 nToBase 进位。
*本函数能够处理2进制到36进制之间任意正数(包括带小数的数值)的相互转换。
*在十进位之前都是以数字表示,而在超过十进位之后就用英文字母表示。
*例如十六进位个位数依序为 123456789abcdef,10 的顺序是第十七个,这时才进一位。
*而三十六进位 a 是第十个、b 为第十一个、z 为第三十六个、10 是第三十七个,这时才进位。
*===================================================================================

*以下为常用的进制使用范例

lc2='1111011.101'
lc8='173.5'
lc10='123.625'
lc16='7B.A'
Clear
?Base_Convert(lc8,8,2)       &&8进制转成2进制
?Base_Convert(lc10,10,2)     &&10进制转成2进制
?Base_Convert(lc16,16,2)     &&16进制转成2进制
?''
?Base_Convert(lc2,2,8)       &&2进制转成8进制
?Base_Convert(lc10,10,8)     &&10进制转成8进制
?Base_Convert(lc16,16,8)     &&16进制转成8进制
?''
?Base_Convert(lc2,2,10)      &&2进制转成10进制
?Base_Convert(lc8,8,10)      &&8进制转成10进制
?Base_Convert(lc16,16,10)    &&16进制转成10进制
?''
?Base_Convert(lc2,2,16)      &&2进制转成16进制
?Base_Convert(lc8,8,16)      &&8进制转成16进制
?Base_Convert(lc10,10,16)    &&10进制转成16进制Function Base_Convert(cNumber,nFromBase,nToBase)
    If Parameters()#3
        Messagebox('参数个数不对!',16,'错误')
        Return ''
    Endif
    If Vartype(cNumber)#'C' Or Vartype(nFromBase)#'N' Or Vartype(nToBase)#'N'Or !Between(nFromBase,2,36) Or !Between(nToBase,2,36)
        Messagebox('参数类型不对!',16,'错误')
        Return ''
    Endif
    Private All
    lnDecBak=Set('DECIMALS')
    Set Decimals To 18
    dict="0123456789ABCDEFGHIJKLMNOPQISTUVWXYZ"
    cNumber=Upper(Alltrim(Transform(cNumber)))
    nDecimalsWZ=At('.',cNumber) &&判断是否带小数
    If nDecimalsWZ>0
        cNumber2=Substr(cNumber,nDecimalsWZ+1)
        cNumber=Left(cNumber,nDecimalsWZ-1)
    Else
        cNumber2=''
    Endif
    dec=0
    n0=Len(cNumber)
    For I=1 To n0
        ch=Substr(cNumber,I,1)
        N=At(ch,dict)
        If !Between(N,1,nFromBase)
            Return ''
        Endif
        dec=dec+(N-1)*nFromBase^(n0-I)
    Endfor
    dec2=0
    n02=Len(cNumber2)
    For I=1 To n02
        ch2=Substr(cNumber2,I,1)
        N2=At(ch2,dict)
        If !Between(N2,1,nFromBase)
            Return ''
        Endif
        dec2=dec2+(N2-1)/nFromBase^I
    Endfor
    If nToBase=10
        Set Decimals To (lnDecBak)
        If dec2=0
            Return Transform(dec)
        Else
            Return numTOstr(dec+dec2)
        Endif
    Endif
    Convert=''
    Do While dec>=nToBase
        N=Mod(dec,nToBase)
        dec=Int(dec/nToBase)
        Convert=Substr(dict,N+1,1)+Convert
    Enddo
    Convert=Substr(dict,dec+1,1)+Convert
    Convert2=''
    Do While dec2>0
        N2=Int(dec2*nToBase)
        dec2=dec2*nToBase-N2
        Convert2=Convert2+Substr(dict,N2+1,1)
    Enddo
    Set Decimals To (lnDecBak)
    If Len(Convert2)>0
        Return Convert+'.'+Convert2
    Else
        Return Convert
    Endif
Endfunc


 

Function numTOstr &&将带小数的数值转换为字符型数值,并去掉后面补位的0

Lparameters lnNum
    Private All
    lnDecBak=Set('DECIMALS')
    Set Decimals To 18
    Do Case
        Case Version(5)<700 &&VFP6及以下
            lcNum=Transform(lnNum) &&VFP6.0时,如果小数部分一样会有问题,如9.2222,转换就变为9.222200000000001
        Case Version(5)>=700 And Version(5)<900 &&VFP7、8
            lcNum=Transform(lnNum)
            If At('.',lcNum)>0
                lnNumLen=Len(lcNum)
                For I=lnNumLen To 1 Step -1
                    If !Substr(lcNum,I,1)=='0'
                        Exit
                    Endif
                Endfor
                lcNum=Left(lCNum,I)
            Endif
        Case Version(5)>=900 &&VFP9及以上
            lcNum=Alltrim(Transform(lnNum),'0')
    Endcase
    Set Decimals To (lnDecBak)
    Return lcNum
Endfunc