| 
			
				|  | 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 樓
 
 |  |  
		| 回頂端 |  |  
		|  |  
		|  |  
  
  	| 
 
 | 您 無法 在這個版面發表文章 您 無法 在這個版面回覆文章
 您 無法 在這個版面編輯文章
 您 無法 在這個版面刪除文章
 您 無法 在這個版面進行投票
 您 無法 在這個版面附加檔案
 您 無法 在這個版面下載檔案
 
 |  |