다음은  대화형 모드(interactive mode)에서 진법 변환(radix conversion)하는 F# 소스 코드이다.

   주: 이 소스는 Python 용으로 만들어 둔 소스를 F# 언어로 바꾼 것이라서
        F# 언어의 명령형 언어 특징을 위주로 짜여져 있다.

메뉴는 주메뉴 Command: (S)et radix, (A)bout, (Q)uit or E(x)it
와 부메뉴 SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
로 구성되어 있으며, 진법 변환의 핵심은 소스 코드에 자체 작성된 함수 atoi(string, radix)와  itoa(number, radix)의 사용이다.

         let value = atoi(str, srcRdx)
         let str = itoa(value, destRdx)

지원되는 진법은 2진법에서 36진법까지이다.

  1. (*
  2.  *  Filename: ConvertRadix.fs
  3.  *            Convert radix in an interactive mode.
  4.  *
  5.  *  Compile: fsc convertRadix.fs
  6.  *  Execute: ConvertRadix
  7.  *
  8.  *      Date:  2010/07/14
  9.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  10.  *)
  11. #light
  12. exception RuntimeError of string
  13. exception ValueError of string
  14. let println s =
  15.     printfn "%O" s
  16. let print s =
  17.     printf "%O" s
  18. let printUsage dummy =
  19.     println "Usage: python convertRadix.py"
  20.     println "Convert radix in a interactive mode, where the maximum radix is 36."
  21. let printAbout dummy =
  22.     println "    About: Convert radix in a interactive mode."
  23. let printMainMenu dummy =
  24.     println "  Command: (S)et radix, (A)bout, (Q)uit or E(x)it"
  25. let printMainPrompt dummy =
  26.     print "  Prompt> "
  27. let printSubMenu srcRadix destRadix =
  28.     println ("    Convert Radix_" + (sprintf "%O" srcRadix) + " to Radix_" + (sprintf "%O" DestRadix) )
  29.     println ("    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit" )
  30. let printSubPrompt dummy =
  31.     print "    Input Value>> "
  32. let BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  33. let itoa (num : int, radix : int) =
  34.    let mutable isNegative = false
  35.    let mutable numx = num
  36.    if num < 0 then
  37.       isNegative <- true
  38.       numx <- (-num)
  39.    let mutable arr = [  ]
  40.    let mutable q = numx
  41.    let mutable r = 0
  42.    while (q >= radix) do
  43.        r <- int (q % radix)
  44.        q <- int (q / radix)
  45.        arr <- List.append arr [ sprintf "%O" (BASE36.[r]) ]
  46.    arr <- List.append arr [ sprintf "%O" (BASE36.[q]) ]
  47.    if isNegative then
  48.       arr <- List.append arr [ "-" ]
  49.    arr <- List.rev arr
  50.    System.String.Join("", List.toArray arr)
  51. let atoi (s : string, radix : int) : int =
  52.     let mutable ret = 0
  53.     let mutable isNegative = false
  54.     let len = s.Length
  55.     let mutable valx = 0
  56.     let mutable c = s.[0]
  57.     if c = '-' then
  58.         isNegative <- true
  59.     elif (c >= '0' && c <= '9') then
  60.         ret <- (int c) - (int '0')
  61.     elif (c >= 'A' && c <= 'Z') then
  62.         ret <- int c - int 'A' + 10
  63.     elif (c >= 'a' && c <= 'z') then
  64.         ret <- int c - int 'a' + 10
  65.     if (ret >= radix) then
  66.         printfn "    Error: Can not read \"%s\" (as radix %d): %O is an invalid character!" s radix ret
  67.     for i = 1 to len - 1 do
  68.         c <- s.[i]
  69.         ret <- ret*radix
  70.         if (c >= '0' && c <= '9') then
  71.             valx <- int c - int '0'
  72.         elif (c >= 'A' && c <= 'Z') then
  73.             valx <- int c - int 'A' + 10
  74.         elif (c >= 'a' && c <= 'z') then
  75.             valx <- int c - int 'a' + 10
  76.         if (valx >= radix) then
  77.             printfn "    Error: Can not read \"%s\" (as radix %d): %O is an invalid character!" s radix c
  78.         ret <- ret + valx
  79.     if (isNegative) then
  80.         ret <- (-ret )
  81.     ret
  82. let convertRadix s srcRdx destRdx =
  83.     let mutable ret = ""
  84.     try
  85.         try
  86.             let valx = atoi (s, srcRdx)
  87.             ret <- itoa (valx, destRdx)
  88.             ret <- ret.ToUpper()
  89.             ret
  90.         with
  91.             | ValueError e -> printfn "    Error: Cannot convert radix %O" srcRdx
  92.                               ret <- "????"
  93.                               ret
  94.     finally
  95.         ret.ToUpper() |> ignore
  96. let doConvert srcRadix destRadix =
  97.     let mutable line = ""
  98.     let mutable cmd = ""
  99.     let mutable srcStr = ""
  100.     let mutable destStr = ""
  101.     printfn ""
  102.     printSubMenu srcRadix  destRadix
  103.     let mutable stop_flag = false
  104.     try
  105.         while not stop_flag do
  106.             printSubPrompt()
  107.             let mutable cmd = System.Console.ReadLine()
  108.             while (String.length cmd) = 0 do
  109.                 cmd <- System.Console.ReadLine()
  110.             if "main()" = cmd then
  111.                 stop_flag <- false
  112.                 raise (RuntimeError ("return to main menu"))
  113.             elif "exit()" = cmd || "quit()" = cmd then
  114.                 exit(0)
  115.             try
  116.                 let dum = atoi(cmd, srcRadix) |> ignore
  117.                 srcStr <- cmd
  118.                 destStr <- (convertRadix srcStr srcRadix destRadix)
  119.                 printfn "        ( %s )_%d   --->   ( %s )_%d" srcStr srcRadix destStr destRadix
  120.                 printfn ""
  121.             with
  122.                 | ValueError e -> println ""
  123.     with
  124.         | RuntimeError e -> printfn "      %O" e
  125. let doStart dummy =
  126.     let mutable line = ""
  127.     let mutable cmd = ""
  128.     let mutable srcRadix = 10
  129.     let mutable destRadix = 10
  130.     let mutable srcStr = ""
  131.     let mutable destStr = ""
  132.     let mutable onlyOnce = true
  133.     let mutable st = [| |]
  134.     try
  135.         while true do
  136.             printfn ""
  137.             if onlyOnce then
  138.                 println "  The supported maximum radix is 36."
  139.                 onlyOnce <- false
  140.             printMainMenu 0
  141.             printMainPrompt 0
  142.             cmd <- System.Console.ReadLine()
  143.             while (String.length cmd) = 0 do
  144.                 cmd <- System.Console.ReadLine()
  145.             if "qQxX".IndexOf(cmd) >= 0 && (String.length cmd) = 1 then
  146.                 exit(0)
  147.             elif "aA".IndexOf(cmd) >= 0 && cmd.Length = 1 then
  148.                 printAbout 0
  149.             elif "sS".IndexOf(cmd) >= 0 && cmd.Length = 1 then
  150.                 print "  Input the source and target radices (say, 16 2): "
  151.                 line <- System.Console.ReadLine()
  152.                 st <- line.Split [| ' ' |]
  153.                 while (Array.length st) < 2 do
  154.                     print ("  Input the source and target radices (say, 16 2): ")
  155.                     line <- System.Console.ReadLine()
  156.                     st <- line.Split [| ' ' |]
  157.                 srcRadix <- int (st.[0])
  158.                 destRadix <- int (st.[1])
  159.                 doConvert srcRadix destRadix
  160.     with
  161.         | RuntimeError e ->  printfn "  Error foune!!"
  162. // Begin here
  163. let cmdArgs = System.Environment.GetCommandLineArgs()
  164. if (Array.length cmdArgs > 1 && "-h" = cmdArgs.[1]) then
  165.     printUsage 0
  166.     exit(1)
  167. doStart 0 |> ignore



컴파일> fsc ConvertRadix.fs

실행> ConvertRadix

  The supported maximum radix is 36.
  Command: (S)et radix, (A)bout, (Q)uit or E(x)it
  Prompt> s
  Input the source and target radices (say, 16 2): 10 8

    Convert Radix_10 to Radix_8
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 200
        ( 200 )_10   --->   ( 310 )_8

    Input Value>> main()

  Command: (S)et radix, (A)bout, (Q)uit or E(x)it
  Prompt> S
  Input the source and target radices (say, 16 2): 8 10

    Convert Radix_8 to Radix_10
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 2666
        ( 2666 )_8   --->   ( 1462 )_10

    Input Value>> main()

  Command: (S)et radix, (A)bout, (Q)uit or E(x)it
  Prompt> x




Posted by Scripter
,