VFP 愛用者社區 首頁 VFP 愛用者社區
本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入

[原創]2 到 36 進位制轉換函數

 
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區
上一篇主題 :: 下一篇主題  
發表人 內容
朱育興



註冊時間: 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 次修改
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件 MSN Messenger
朱育興



註冊時間: 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
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件 MSN Messenger
goto-dream



註冊時間: 2004-05-11
文章: 909


第 3 樓

發表發表於: 星期日 十二月 06, 2009 1:39 am    文章主題: 引言回覆

謝謝....朱大的分享
_________________
福隆昌淨水有限公司--淨水器的專家,淨水器,飲水機,濾心!!

想了解更多,您可上幸福雞湯組.找尋!!丁澐瑄.老師.

          愛作夢
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件
從之前的文章開始顯示:   
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區 所有的時間均為 台北時間 (GMT + 8 小時)
1頁(共1頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
無法 在這個版面附加檔案
無法 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作