 |
VFP 愛用者社區 本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.
|
上一篇主題 :: 下一篇主題 |
發表人 |
內容 |
朱育興
註冊時間: 2003-08-25 文章: 661 來自: 台中市大里區
第 1 樓
|
發表於: 星期一 五月 17, 2004 2:15 pm 文章主題: [轉帖][推薦]進制轉換(可帶小數) |
|
|
[推薦]進制轉換(可帶小數)
* 這是 Myf1論壇 狐說八道 所改寫的!
* 出處:http://www.myf1.net/bbs/dispbbs.asp?boardid=1&id=251264&star=1#311528
clear
****test1
abc='11111111.111'
l_target = 10
l_source = 2
xyz=DECITRAN(abc, , , 4, 3 )
?abc + '(' + alltrim(str(l_source)) + ')<——>' + xyz + '('+ alltrim(str(l_target)) + ')'
abc='255.875'
l_target = 2
l_source = 10
xyz=DECITRAN(abc, l_target, l_source, 4, 3 )
?abc + '(' + alltrim(str(l_source)) + ')<——>' + xyz + '('+ alltrim(str(l_target)) + ')'
****test2
abc='1024.75'
l_target = 16
l_source = 10
xyz=DECITRAN(abc, l_target, l_source, 4, 4 )
?abc + '(' + alltrim(str(l_source)) + ')<——>' + xyz + '('+ alltrim(str(l_target)) + ')'
abc='400.c'
l_target = 10
l_source = 16
xyz=DECITRAN(abc, l_target, l_source, 4, 4 )
?abc + '(' + alltrim(str(l_source)) + ')<——>' + xyz + '('+ alltrim(str(l_target)) + ')'
代碼: | *2 到 36 進位制轉換函數
FUNCTION DECITRAN
* 源碼:2004/04/27 朱育興 YSC5096 E-Mail:y5096@ms23.hinet.net
* 改編:2004/05/14 狐說八道 E-Mail:bhq@king-land.com.cn
* 改進:1。後4個參數可用預?#93;參數?#93;僅逗號)
* 2。增?#93;第5個參數來指定轉換後的小數位數
* 3。增?#91;小數部分的進制轉換
* 調整:1。L_cNum 的資料合理性檢驗算法
* 2。整數進制轉換部分的算法
* 函數語法:DECITRAN(L_cNum[,L_nTDecimal[,L_nSDecimal[,L_nTNumLen[,L_nTdecLen]]]])
* 參數說明:
* --------------------------------------------------------------------------------------
* 參數名稱 型態 說明
* --------------------------------------------------------------------------------------
* Input : L_cNum C 1.代表要轉換的字元型態的數值。
* 2.此數值依 2 到 36 進位制所表達的數值。
* 3.只接受 0 到 9、A 到 Z 之間的字元;a 到 z 會被?#123;定為大寫
* (L_nTDecimal) N 1.代表要轉為幾進位制。
* 2.本參數的範圍為 2 到 36 的整數,超出此範圍會依近似原則
* 自動修正。
* 3.若忽略本參數,其預?#93;值 = 10。
* (L_nSDecimal) N 1.代表 L_cNum 為幾進位制。
* 2.本參數的範圍為 2 到 36 的整數。
* A.超出此範圍會依近似原則自動修正。
* B.若依 L_cNum 的內容自動判斷的位數大於指定的 L_nSDecimal
* 值,則依下列 3. 之範例修正。
* 3.若忽略本參數,其預?#93;值依 L_cNum 的內容自動判斷。
* 例如:L_cNum = "123456" -> L_nSDecimal = 7
* L_cNum = "12ABC6" -> L_nSDecimal = 13
* (L_nTNumLen) N 1.代表 Wo_cTNum 的整數長度。
* 2.本參數為非負整數。
* A.超出此範圍會依近似原則自動修正。
* B.0 代表依 Wo_cTNum 的實際長度傳回。
* 3.若忽略本參數,其預?#93;值 = 0。
* (L_nTdecLen) N 1.代表 Wo_cTNum 的小數位數長度。
* 2.本參數為非負整數且<=10(精度沒必要太高)。
* A.超出此範圍會依近似原則自動修正。
* B.0 代表只按 Wo_cTNum 的整數長度傳回。
* 3.若忽略本參數,其預?#93;值 = 0。
* Output: Wo_cTNum C 1.代表傳回所指定之 L_nTDecimal 中之指定進位制的字元型態的
* 數值。
* 2.若 L_cNum 值不符合規定,則傳回 0 這個字元。
* 3.若 Input 參數群之型態宣告不正確,則傳回 0 這個字元。
* 4.若 Wo_cTNum 傳回的長度大於或等於 L_nTNumLen,則依
* Wo_cTNum 的實際長度傳回。小於時,其前置位數補 0。
* --------------------------------------------------------------------------------------
* 範例:? DECITRAN("1024",16,10) -> 400
* ? DECITRAN("1024",16,10,2) -> 400
* ? DECITRAN("1024",16,10,4) -> 0400
* ? DECITRAN("1024",16,10,8) -> 00000400
* --------------------------------------------------------------------------------------
* 說明:
* 1. 會想到寫這個函數,是看了「梅子論壇」的狐友「武裝部長」寫的「任意進制類」,他是將
* 10 進位的數值轉換為 11 到 36 進位,他將它?#93;裝為一個 hexchange.vcx。
* 2. 只是基於好玩,想以函數的模樣來做這個功能,並擴充其範圍;僅供同好參考。
* 3. 第 4 個參數 L_nTNumLen 是依 Myf1論壇 版主 gz 的建議?#91;入的。
* *************************************************************************** *
* 參數檢驗 *
* *************************************************************************** *
LPARAMETERS L_cNum,L_nTDecimal,L_nSDecimal,L_nTNumLen,L_nTdecLen
LOCAL may_value, W1_c1Digit, W1_n1Num, LL_cNum, L_times
LOCAL W1_SUB_A,W1_nNum, W1_nDecNum, Wo_cTNum
* 參數個數檢查?#93;預?#93;值)
L_nTdecLen = iif( PCOUNT()<=4 or empty( L_nTdecLen ), 0, L_nTdecLen )
L_nTNumLen = iif( PCOUNT()<=3 or empty( L_nTNumLen ), 0, L_nTNumLen )
L_nSDecimal = iif( PCOUNT()<=2 or empty( L_nSDecimal ), 2, L_nSDecimal )
L_nTDecimal = iif( PCOUNT()<=1 or empty( L_nTDecimal ), 10, L_nTDecimal )
* 參數類型檢驗
if vartype(L_cNum)!='C' or vartype(L_nTDecimal)!='N' or vartype(L_nSDecimal)!='N' or ;
vartype(L_nTNumLen)!='N' or vartype(L_nTdecLen)!='N'
return '0' &&或傳回提示、或傳回錯誤代碼?#93;負數)
endif
* 參數值檢驗及規範
* > 1.a. L_nSDecimal 與 L_nTDecimal 必須介於 2 - 36
* b. L_nTNumLen 必須為非負整數
* c. L_nTdecLen 必須為非負整數且<=10(精度沒必要太高)
*!* L_nSDecimal = iif( abs(L_nSDecimal)<2, 2, MIN(round(abs(L_nSDecimal),0),36) )
if L_nTDecimal < 2 or L_nTDecimal > 36
RETURN "0" &&或傳回提示、或傳回錯誤代碼?#93;負數)
endif
*!* L_nTDecimal = iif( abs(L_nTDecimal)<2, 10, MIN(round(abs(L_nTDecimal),0),36) )
if L_nTDecimal < 2 or L_nTDecimal > 36
RETURN "0" &&或傳回提示、或傳回錯誤代碼?#93;負數)
endif
if L_nTdecLen < 0 or L_nTdecLen > 10
RETURN "0" &&或傳回提示、或傳回錯誤代碼?#93;負數)
endif
* > 2.a. L_cNum 中每個字元必須為 0 - 9、A - Z(a - z 自動轉為 A - Z)
* b. L_cNum 與 L_nSDecimal 之間的合理性
IF PCOUNT() = 0 or EMPTY(L_cNum) or OCCURS('.', L_cNum) > 1
RETURN "0" &&或傳回提示、或傳回錯誤代碼?#93;負數)
ENDIF
L_cNum = alltrim( UPPER(L_cNum) )
may_value = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
if ! empty( chrtran(L_cNum, '.' + left( may_value, L_nSDecimal ), '') )
RETURN "0" &&或傳回提示、或傳回錯誤代碼?#93;負數)
endif
L_nTdecLen = MIN(round(abs(L_nTdecLen),0),10)
L_nTNumLen = round(abs(L_nTNumLen),0)
* *************************************************************************** *
* ?#123;式碼區 *
* *************************************************************************** *
* 將 L_nSDecimal 進位制的數?#93;L_cNum) 轉換為 10 進位制的數?#93;W1_nNum)
* 整數轉換:
LL_cNum = left( L_cNum, at( '.', L_cNum + '.' ) - 1 )
W1_nNum = 0
FOR W1_SUB_A = 1 TO LEN(LL_cNum)
W1_c1Digit = SUBSTR(LL_cNum,W1_SUB_A,1)
W1_c1Digit = IIF( ISDIGIT(W1_c1Digit), VAL(W1_c1Digit), ASC(W1_c1Digit) - 55 )
W1_nNum = ( W1_nNum + W1_c1Digit ) * iif( W1_SUB_A < LEN(LL_cNum), L_nSDecimal, 1 )
ENDFOR
* 將 10 進位制的數?#93;W1_nNum) 轉換為 L_nTDecimal 進位制的數?#93;Wo_cTNum)
* 整數轉換:
Wo_cTNum = SPACE(0)
DO WHILE W1_nNum > 0
W1_c1Digit = MOD(W1_nNum,L_nTDecimal)
W1_nNum = INT(W1_nNum/L_nTDecimal)
Wo_cTNum = substr( may_value, W1_c1Digit + 1, 1 ) + Wo_cTNum
ENDDO
Wo_cTNum = IIF( LEN(Wo_cTNum) < L_nTNumLen, PADL(Wo_cTNum,L_nTNumLen,"0"), Wo_cTNum )
if L_nTdecLen = 0 && 0 代表只按 Wo_cTNum 的整數長度傳回。
RETURN Wo_cTNum
endif
******************** 以下由 狐說八道 增補 *****************************
* 將 L_nSDecimal 進位制的數?#93;L_cNum) 轉換為 10 進位制的數?#93;W1_nNum)
* 小數轉換:
LL_cNum = right( L_cNum, len(L_cNum) - len(LL_cNum) - 1 )
W1_nNum = 0
FOR W1_SUB_A = LEN(LL_cNum) to 1 step -1
W1_c1Digit = SUBSTR(LL_cNum,W1_SUB_A,1)
W1_c1Digit = IIF( ISDIGIT(W1_c1Digit), VAL(W1_c1Digit), ASC(W1_c1Digit) - 55 )
W1_nNum = ( W1_nNum + W1_c1Digit ) / L_nSDecimal
ENDFOR
* 將 10 進位制的數?#93;W1_nNum) 轉換為 L_nTDecimal 進位制的數?#93;W1_nDecNum)
* 小數轉換:
L_times = 0
W1_nDecNum = space(0)
DO WHILE W1_nNum > 0 and L_times <= L_nTdecLen
W1_c1Digit = int( W1_nNum*L_nTDecimal )
W1_nNum = mod( W1_nNum*L_nTDecimal, 1 )
W1_nDecNum = W1_nDecNum + substr( may_value, W1_c1Digit + 1, 1 )
L_times = L_times + 1
ENDDO
W1_nDecNum = left( W1_nDecNum + REPLICATE( '0', L_nTdecLen ), L_nTdecLen )
RETURN Wo_cTNum + '.' + W1_nDecNum
endfunc |
_________________ 希望有更多人來參與
VFP wiki - 需要大家一起完成的VFP電子書與FAQ |
|
回頂端 |
|
 |
|
|
您 無法 在這個版面發表文章 您 無法 在這個版面回覆文章 您 無法 在這個版面編輯文章 您 無法 在這個版面刪除文章 您 無法 在這個版面進行投票 您 無法 在這個版面附加檔案 您 無法 在這個版面下載檔案
|
|