|
VFP 愛用者社區 本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.
|
上一篇主題 :: 下一篇主題 |
發表人 |
內容 |
朱育興
註冊時間: 2003-08-25 文章: 661 來自: 台中市大里區
第 1 樓
|
發表於: 星期日 四月 25, 2004 3:43 am 文章主題: [原創]2 到 36 進位制轉換函數 |
|
|
增加第 4 個參數,在下一篇
代碼: | FUNCTION DECITRAN
* 2004/04/25 朱育興 YSC5096 E-Mail:y5096@ms23.hinet.net
* 參數說明:
* --------------------------------------------------------------------------------------
* 參數名稱 型態 說明
* --------------------------------------------------------------------------------------
* 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
* Output: Wo_cTNum C 1.代表傳回所指定之 L_nTDecimal 中之指定進位制的字元型態的
* 數值。
* 2.若 L_cNum 值不符合規定,則傳回 0 這個字元。
* --------------------------------------------------------------------------------------
* 說明:
* 1. 會想到寫這個函數,是看了「梅子論壇」的狐友「武裝部隊」寫的「任意進制類」,他是將
* 10 進位的數值轉換為 11 到 36 進位,他將它?#93;裝為一個 hexchange.vcx。
* 2. 只是基於好玩,想以函數的模樣來做這個功能,並擴充其範圍;僅供同好參考。
* *************************************************************************** *
* 參數檢驗 *
* *************************************************************************** *
LPARAMETERS L_cNum,L_nTDecimal,L_nSDecimal
LOCAL Wi_cNum,Wi_nTDecimal,Wi_nSDecimal
LOCAL Wo_cTNum
LOCAL W1_SUB_A,W1_c1Digit,W1_n1Num
LOCAL W1_SUB_B,W1_nNum,W1_n1Digit,W1_nBase,W1_nremainder
* 初始值
DO CASE
CASE PCOUNT() = 2
L_nSDecimal = 2
CASE PCOUNT() = 1
L_nTDecimal = 10
L_nSDecimal = 2
CASE PCOUNT() = 0
RETURN "0"
ENDCASE
* 型態
IF TYPE("L_cNum") != "C" OR ;
TYPE("L_nSDecimal") != "N" OR ;
TYPE("L_nTDecimal") != "N"
RETURN "0"
ENDIF
* 合理性
* > 1.L_nSDecimal 與 L_nTDecimal 必須介於 2 - 36
L_nTDecimal = MIN(MAX(INT(L_nTDecimal),2),36)
L_nSDecimal = MIN(MAX(INT(L_nSDecimal),2),36)
* > 2.a. L_cNum 不是空字串
* b. L_cNum 中每個字元必須為 0 - 9、A - Z(a - z 自動轉為 A - Z)
* c. L_cNum 與 L_nSDecimal 之間的合理性
IF EMPTY(L_cNum)
RETURN "0"
ENDIF
L_cNum = UPPER(L_cNum)
FOR W1_SUB_A = 1 TO LEN(L_cNum)
W1_c1Digit = SUBSTR(L_cNum,W1_SUB_A,1)
DO CASE
CASE ISDIGIT(W1_c1Digit)
L_nSDecimal = MAX(VAL(W1_c1Digit)+1,L_nSDecimal)
CASE ISALPHA(W1_c1Digit)
L_nSDecimal = MAX(ASC(W1_c1Digit)-54,L_nSDecimal)
OTHERWISE
RETURN "0"
ENDCASE
ENDFOR
* > 3.當修正後的 L_nSDecimal 與 L_nTDecimal 相同時,不做轉換
IF L_nSDecimal = L_nTDecimal
RETURN L_cNum
ENDIF
* *************************************************************************** *
* ?#123;式碼區 *
* *************************************************************************** *
* 初始值?#93;定
Wi_cNum = L_cNum
Wi_nSDecimal = L_nSDecimal
Wi_nTDecimal = L_nTDecimal
Wo_cTNum = SPACE(0)
* 將 Wi_cNum 轉換為 10 進鴩謇獐ぉ?W1_nNum
W1_nNum = 0
FOR W1_SUB_A = 1 TO LEN(Wi_cNum)
W1_c1Digit = SUBSTR(Wi_cNum,W1_SUB_A,1)
IF ISDIGIT(W1_c1Digit)
W1_n1Digit = VAL(W1_c1Digit)
ELSE
W1_n1Digit = ASC(W1_c1Digit) - 55
ENDIF
W1_nBase = 1
FOR W1_SUB_B = 1 TO LEN(Wi_cNum)-W1_SUB_A
W1_nBase = W1_nBase * Wi_nSDecimal
ENDFOR
W1_nNum = W1_nNum + W1_n1Digit * W1_nBase
ENDFOR
* 求出 Wo_cTNum
DO WHILE W1_nNum > 0
W1_nremainder = MOD(W1_nNum,Wi_nTDecimal)
W1_nNum = INT(W1_nNum/Wi_nTDecimal)
IF W1_nremainder < 10
Wo_cTNum = LTRIM(STR(W1_nremainder)) + Wo_cTNum
ELSE
Wo_cTNum = CHR(W1_nremainder+55) + Wo_cTNum
ENDIF
ENDDO
RETURN Wo_cTNum |
_________________ 希望有更多人來參與
VFP wiki - 需要大家一起完成的VFP電子書與FAQ
朱育興 在 星期五 五月 14, 2004 1:07 am 作了第 2 次修改 |
|
回頂端 |
|
|
朱育興
註冊時間: 2003-08-25 文章: 661 來自: 台中市大里區
第 2 樓
|
發表於: 星期二 四月 27, 2004 10:16 pm 文章主題: |
|
|
增加第 4 個參數
代碼: | FUNCTION DECITRAN
* 2004/04/27 朱育興 YSC5096 E-Mail:y5096@ms23.hinet.net
* 函數語法:DECITRAN(L_cNum[,L_nTDecimal[,L_nSDecimal[,L_nTNumLen]]])
* 參數說明:
* --------------------------------------------------------------------------------------
* 參數名稱 型態 說明
* --------------------------------------------------------------------------------------
* 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。
* 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
LOCAL Wi_cNum,Wi_nTDecimal,Wi_nSDecimal,Wi_nTNumLen
LOCAL Wo_cTNum
LOCAL W1_SUB_A,W1_c1Digit,W1_n1Num
LOCAL W1_SUB_B,W1_nNum,W1_n1Digit,W1_nBase,W1_nremainder
* 初始值
DO CASE
CASE PCOUNT() = 3
L_nTNumLen = 0
CASE PCOUNT() = 2
L_nSDecimal = 2
L_nTNumLen = 0
CASE PCOUNT() = 1
L_nTDecimal = 10
L_nSDecimal = 2
L_nTNumLen = 0
CASE PCOUNT() = 0
RETURN "0"
ENDCASE
* 型態
IF TYPE("L_cNum") != "C" OR ;
TYPE("L_nSDecimal") != "N" OR ;
TYPE("L_nTDecimal") != "N" OR ;
TYPE("L_nTNumLen") != "N"
RETURN "0"
ENDIF
* 合理性
* > 1.a. L_nSDecimal 與 L_nTDecimal 必須介於 2 - 36
* b. L_nTNumLen 必須為非負整數
L_nTDecimal = MIN(MAX(INT(L_nTDecimal),2),36)
L_nSDecimal = MIN(MAX(INT(L_nSDecimal),2),36)
L_nTNumLen = MAX(INT(L_nTNumLen),0)
* > 2.a. L_cNum 不是空字串
* b. L_cNum 中每個字元必須為 0 - 9、A - Z(a - z 自動轉為 A - Z)
* c. L_cNum 與 L_nSDecimal 之間的合理性
IF EMPTY(L_cNum)
RETURN "0"
ENDIF
L_cNum = UPPER(L_cNum)
FOR W1_SUB_A = 1 TO LEN(L_cNum)
W1_c1Digit = SUBSTR(L_cNum,W1_SUB_A,1)
DO CASE
CASE ISDIGIT(W1_c1Digit)
L_nSDecimal = MAX(VAL(W1_c1Digit)+1,L_nSDecimal)
CASE ISALPHA(W1_c1Digit)
L_nSDecimal = MAX(ASC(W1_c1Digit)-54,L_nSDecimal)
OTHERWISE
RETURN "0"
ENDCASE
ENDFOR
* *************************************************************************** *
* ?#123;式碼區 *
* *************************************************************************** *
* 初始值?#93;定
Wi_cNum = L_cNum
Wi_nTDecimal = L_nTDecimal
Wi_nSDecimal = L_nSDecimal
Wi_nTNumLen = L_nTNumLen
Wo_cTNum = SPACE(0)
* 將 Wi_cNum 轉換為 10 進位制的數值 W1_nNum
W1_nNum = 0
FOR W1_SUB_A = 1 TO LEN(Wi_cNum)
W1_c1Digit = SUBSTR(Wi_cNum,W1_SUB_A,1)
IF ISDIGIT(W1_c1Digit)
W1_n1Digit = VAL(W1_c1Digit)
ELSE
W1_n1Digit = ASC(W1_c1Digit) - 55
ENDIF
W1_nBase = 1
FOR W1_SUB_B = 1 TO LEN(Wi_cNum)-W1_SUB_A
W1_nBase = W1_nBase * Wi_nSDecimal
ENDFOR
W1_nNum = W1_nNum + W1_n1Digit * W1_nBase
ENDFOR
* 求出 Wo_cTNum
DO WHILE W1_nNum > 0
W1_nremainder = MOD(W1_nNum,Wi_nTDecimal)
W1_nNum = INT(W1_nNum/Wi_nTDecimal)
IF W1_nremainder < 10
Wo_cTNum = LTRIM(STR(W1_nremainder)) + Wo_cTNum
ELSE
Wo_cTNum = CHR(W1_nremainder+55) + Wo_cTNum
ENDIF
ENDDO
IF LEN(Wo_cTNum) < Wi_nTNumLen
Wo_cTNum = PADL(Wo_cTNum,Wi_nTNumLen,"0")
ENDIF
RETURN Wo_cTNum |
_________________ 希望有更多人來參與
VFP wiki - 需要大家一起完成的VFP電子書與FAQ |
|
回頂端 |
|
|
goto-dream
註冊時間: 2004-05-11 文章: 909
第 3 樓
|
|
回頂端 |
|
|
|
|
您 無法 在這個版面發表文章 您 無法 在這個版面回覆文章 您 無法 在這個版面編輯文章 您 無法 在這個版面刪除文章 您 無法 在這個版面進行投票 您 無法 在這個版面附加檔案 您 無法 在這個版面下載檔案
|
|