다음은 대화형 모드(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진법까지이다.
- (*
- * Filename: ConvertRadix.fs
- * Convert radix in an interactive mode.
- *
- * Compile: fsc convertRadix.fs
- * Execute: ConvertRadix
- *
- * Date: 2010/07/14
- * Author: PH Kim [ pkim (AT) scripts.pe.kr ]
- *)
- #light
- exception RuntimeError of string
- exception ValueError of string
- let println s =
- printfn "%O" s
- let print s =
- printf "%O" s
- let printUsage dummy =
- println "Usage: python convertRadix.py"
- println "Convert radix in a interactive mode, where the maximum radix is 36."
- let printAbout dummy =
- println " About: Convert radix in a interactive mode."
- let printMainMenu dummy =
- println " Command: (S)et radix, (A)bout, (Q)uit or E(x)it"
- let printMainPrompt dummy =
- print " Prompt> "
- let printSubMenu srcRadix destRadix =
- println (" Convert Radix_" + (sprintf "%O" srcRadix) + " to Radix_" + (sprintf "%O" DestRadix) )
- println (" SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit" )
- let printSubPrompt dummy =
- print " Input Value>> "
- let BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- let itoa (num : int, radix : int) =
- let mutable isNegative = false
- let mutable numx = num
- if num < 0 then
- isNegative <- true
- numx <- (-num)
- let mutable arr = [ ]
- let mutable q = numx
- let mutable r = 0
- while (q >= radix) do
- r <- int (q % radix)
- q <- int (q / radix)
- arr <- List.append arr [ sprintf "%O" (BASE36.[r]) ]
- arr <- List.append arr [ sprintf "%O" (BASE36.[q]) ]
- if isNegative then
- arr <- List.append arr [ "-" ]
- arr <- List.rev arr
- System.String.Join("", List.toArray arr)
- let atoi (s : string, radix : int) : int =
- let mutable ret = 0
- let mutable isNegative = false
- let len = s.Length
- let mutable valx = 0
- let mutable c = s.[0]
- if c = '-' then
- isNegative <- true
- elif (c >= '0' && c <= '9') then
- ret <- (int c) - (int '0')
- elif (c >= 'A' && c <= 'Z') then
- ret <- int c - int 'A' + 10
- elif (c >= 'a' && c <= 'z') then
- ret <- int c - int 'a' + 10
- if (ret >= radix) then
- printfn " Error: Can not read \"%s\" (as radix %d): %O is an invalid character!" s radix ret
- for i = 1 to len - 1 do
- c <- s.[i]
- ret <- ret*radix
- if (c >= '0' && c <= '9') then
- valx <- int c - int '0'
- elif (c >= 'A' && c <= 'Z') then
- valx <- int c - int 'A' + 10
- elif (c >= 'a' && c <= 'z') then
- valx <- int c - int 'a' + 10
- if (valx >= radix) then
- printfn " Error: Can not read \"%s\" (as radix %d): %O is an invalid character!" s radix c
- ret <- ret + valx
- if (isNegative) then
- ret <- (-ret )
- ret
- let convertRadix s srcRdx destRdx =
- let mutable ret = ""
- try
- try
- let valx = atoi (s, srcRdx)
- ret <- itoa (valx, destRdx)
- ret <- ret.ToUpper()
- ret
- with
- | ValueError e -> printfn " Error: Cannot convert radix %O" srcRdx
- ret <- "????"
- ret
- finally
- ret.ToUpper() |> ignore
- let doConvert srcRadix destRadix =
- let mutable line = ""
- let mutable cmd = ""
- let mutable srcStr = ""
- let mutable destStr = ""
- printfn ""
- printSubMenu srcRadix destRadix
- let mutable stop_flag = false
- try
- while not stop_flag do
- printSubPrompt()
- let mutable cmd = System.Console.ReadLine()
- while (String.length cmd) = 0 do
- cmd <- System.Console.ReadLine()
- if "main()" = cmd then
- stop_flag <- false
- raise (RuntimeError ("return to main menu"))
- elif "exit()" = cmd || "quit()" = cmd then
- exit(0)
- try
- let dum = atoi(cmd, srcRadix) |> ignore
- srcStr <- cmd
- destStr <- (convertRadix srcStr srcRadix destRadix)
- printfn " ( %s )_%d ---> ( %s )_%d" srcStr srcRadix destStr destRadix
- printfn ""
- with
- | ValueError e -> println ""
- with
- | RuntimeError e -> printfn " %O" e
- let doStart dummy =
- let mutable line = ""
- let mutable cmd = ""
- let mutable srcRadix = 10
- let mutable destRadix = 10
- let mutable srcStr = ""
- let mutable destStr = ""
- let mutable onlyOnce = true
- let mutable st = [| |]
- try
- while true do
- printfn ""
- if onlyOnce then
- println " The supported maximum radix is 36."
- onlyOnce <- false
- printMainMenu 0
- printMainPrompt 0
- cmd <- System.Console.ReadLine()
- while (String.length cmd) = 0 do
- cmd <- System.Console.ReadLine()
- if "qQxX".IndexOf(cmd) >= 0 && (String.length cmd) = 1 then
- exit(0)
- elif "aA".IndexOf(cmd) >= 0 && cmd.Length = 1 then
- printAbout 0
- elif "sS".IndexOf(cmd) >= 0 && cmd.Length = 1 then
- print " Input the source and target radices (say, 16 2): "
- line <- System.Console.ReadLine()
- st <- line.Split [| ' ' |]
- while (Array.length st) < 2 do
- print (" Input the source and target radices (say, 16 2): ")
- line <- System.Console.ReadLine()
- st <- line.Split [| ' ' |]
- srcRadix <- int (st.[0])
- destRadix <- int (st.[1])
- doConvert srcRadix destRadix
- with
- | RuntimeError e -> printfn " Error foune!!"
- // Begin here
- let cmdArgs = System.Environment.GetCommandLineArgs()
- if (Array.length cmdArgs > 1 && "-h" = cmdArgs.[1]) then
- printUsage 0
- exit(1)
- 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
'프로그래밍 > F#' 카테고리의 다른 글
7비트 ASCII 코드표 만들기 예제 with F# (0) | 2010.07.15 |
---|---|
진법(radix) 표 만들기 예제 with F# (0) | 2010.07.15 |
황금비율(golden ratio) 구하기 with F# (0) | 2010.07.13 |
현재 시각 알아내기 for F# (0) | 2010.07.13 |
80컬럼 컨솔에 19단표 출력하기 예제 for F# (0) | 2010.07.13 |