다음은 대화형 모드(interactive mode)에서 진법 변환(radix conversion)하는 Go 언어 소스 코드이다.
메뉴는 주메뉴 Command: (S)et radix, (A)bout, (Q)uit or E(x)it
와 부메뉴 SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
로 구성되어 있으며, 진법 변환을 하는 핵심 함수 convertAtoI()와 convertItoA()의 소스가 자체 제작되어 포함되어 있다. 이를 이용하는 부분은 152~153째 줄에 있는
val = convertAtoI(s, srcRdx)
ret = convertItoA(val, destRdx)
이다. 지원되는 진법은 2진법에서 36진법 까지이다.
- /*
- * Filename: convertRadix.go
- *
- * Convert radix in a interactive mode.
- *
- * Execute: go run convertRadix.go
- *
- * or
- *
- * Compile: go build convertRadix.go
- * Execute: ./convertRadix
- *
- * Date: 2012/06/25
- * Author: PH Kim [ pkim (AT) scripts.pe.kr ]
- */
- package main
- import (
- "fmt"
- "bufio"
- "os"
- "strings"
- )
- type _TOKEN struct {
- a string
- b string
- }
- func println(s string) {
- fmt.Printf("%s\n", s)
- }
- func print(s string) {
- fmt.Printf("%s", s)
- }
- func printUsage() {
- println("Usage: convertRadix")
- println("Convert radix in an interactive mode, where the maximum radix is 36.")
- }
- func printAbout() {
- println(" About: Convert radix in a interactive mode.")
- }
- func printMainMenu() {
- println(" Command: (S)etup radix, (A)bout, (Q)uit or E(x)it")
- }
- func printMainPrompt() {
- print(" Prompt> ")
- }
- func printSubMenu(srcRadix int, destRadix int) {
- var sbuf string
- fmt.Sprintf(sbuf, " Convert Radix_%d to Radix_%d", srcRadix, destRadix);
- println(sbuf);
- println(" SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit");
- }
- func printSubPrompt() {
- print(" Input Value>> ");
- }
- func convertItoA(num int64, radix int) (ret string) {
- var BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- var tmp string
- var arr string
- var q, r int64
- var i, n int
- var isNegative bool = false
- if num < 0 {
- isNegative = true
- num = -num
- }
- arr = ""
- q = num
- r = 0
- for q >= int64(radix) {
- r = q % int64(radix)
- q = q / int64(radix)
- tmp = BASE36[r:r+1]
- arr += tmp
- }
- tmp = BASE36[q:q+1]
- arr += tmp
- if isNegative {
- arr += "-"
- }
- n = len(arr)
- for i = 0; i < n; i++ {
- ret += arr[n - i - 1:n-i]
- }
- return ret
- }
- func convertAtoI(str string, radix int) (ret int64) {
- var isNegative bool = false
- var len int = len(str)
- var c byte
- var i int
- var val int64
- c = str[0]
- if c == '-' {
- isNegative = true
- } else if c >= '0' && c <= '9' {
- ret = int64(c) - int64('0')
- } else if c >= 'A' && c <= 'Z' {
- ret = int64(c - 'A') + 10
- } else if c >= 'a' && c <= 'z' {
- ret = int64(c - 'a') + 10
- }
- if ret >= int64(radix) {
- println(" Invalid character!")
- return ret
- }
- for i = 1; i < len; i++ {
- c = str[i]
- ret *= int64(radix)
- if c >= '0' && c <= '9' {
- val = int64(c - '0')
- } else if c >= 'A' && c <= 'Z' {
- val = int64(c - 'A') + 10
- } else if c >= 'a' && c <= 'z' {
- val = int64(c - 'a') + 10
- }
- if val >= int64(radix) {
- println(" Invalid character!")
- return ret
- }
- ret += val
- }
- if isNegative {
- ret = -ret
- }
- return ret
- }
- func convertRadix(s string, srcRdx int, destRdx int) (ret string) {
- var val int64
- val = convertAtoI(s, srcRdx)
- ret = convertItoA(val, destRdx)
- return ret
- }
- func readLine() (data string) {
- fmt.Scanf(data, "%s") //
- return data
- }
- func readTwo() (token _TOKEN) {
- token.a = ""
- token.b = ""
- fmt.Scanf("%s %s", &token.a, &token.b) // call twice, is It a bug?
- fmt.Scanf("%s %s", &token.a, &token.b) // call twice, is It a bug?
- return token
- }
- func tokenize(ptoken _TOKEN, line string, c byte) {
- var i int
- var from, to int
- i = 0
- for line[i] != c {
- i += 1
- }
- from = i
- for line[i] == c {
- i += 1
- }
- to = i
- ptoken.a = line[0: to - from]
- for line[i] != c {
- i += 1
- }
- from = i
- for line[i] == c {
- i += 1
- }
- to = i
- ptoken.b = line[0: to - from]
- }
- func doConvert(srcRadix int,destRadix int) {
- var sbuf string
- var cmd string
- var srcStr string
- var destStr string
- println("")
- printSubMenu(srcRadix, destRadix)
- for {
- printSubPrompt()
- cmd = ""
- fmt.Scanf("%s", &cmd) // call twice, is It a bug?
- for cmd == "" {
- fmt.Scanf("%s", &cmd) // call twice, is It a bug?
- }
- if cmd == "main()" {
- return
- } else if cmd == "exit()" || cmd == "quit()" {
- os.Exit(0)
- } '
- srcStr = cmd
- destStr = convertRadix(srcStr, srcRadix, destRadix)
- sbuf = fmt.Sprintf(" ( %s )_%d ---> ( %s )_%d", srcStr, srcRadix, destStr, destRadix);
- println(sbuf)
- println("")
- }
- }
- func doStart() {
- var srcRadix int = 10
- var destRadix int = 10
- var st _TOKEN
- var onlyOnce bool = true
- for {
- println("")
- if onlyOnce {
- println(" The supported maximum radix is 36.")
- onlyOnce = false
- }
- printMainMenu()
- printMainPrompt()
- var cmd string = ""
- fmt.Scanf("%s", &cmd) // call twice, is It a bug?
- fmt.Scanf("%s", &cmd) // call twice, is It a bug?
- if len(cmd) == 1&& strings.IndexAny("qQxX", cmd) >= 0 {
- os.Exit(0)
- } else if len(cmd) == 1&& strings.IndexAny("aA", cmd) >= 0 {
- printAbout()
- } else if len(cmd) == 1&& strings.IndexAny("sS", cmd) >= 0 {
- print(" Input the source and target radices (say, 16 2): ")
- st = readTwo()
- srcRadix = int(convertAtoI(st.a, 10))
- destRadix = int(convertAtoI(st.b, 10))
- doConvert(srcRadix, destRadix)
- }
- }
- }
- func waitCommand(str string) string {
- print(str)
- reader := bufio.NewReader(os.Stdin)
- input, _ := reader.ReadString('\n')
- if len(input) > 0 && input[len(input) -1] == '\n' {
- input = input[0:len(input) -1]
- }
- if len(input) > 0 && input[len(input) -1] == '\r' {
- input = input[0:len(input) -1]
- }
- return input
- }
- func main() {
- if len(os.Args) > 1 && os.Args[1] == "-h" {
- printUsage()
- return
- }
- doStart()
- }
실행> go run convertRadix.go
또는
컴파일> go build convertRadix.go
실행> ./convertRadix
The supported maximum radix is 36.
Command: (S)etup radix, (A)bout, (Q)uit or E(x)it
Prompt> s
Input the source and target radices (say, 16 2): 8 16
Convert Radix_8 to Radix_16
SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
Input Value>> 1234
( 1234 )_8 ---> ( 29C )_16
Input Value>> main()
Command: (S)etup radix, (A)bout, (Q)uit or E(x)it
Prompt> s
Input the source and target radices (say, 16 2): 16 8
Convert Radix_16 to Radix_8
SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
Input Value>> 29c
( 29c )_16 ---> ( 1234 )_8
Input Value>> exit()
'프로그래밍 > Go' 카테고리의 다른 글
7비트 ASCII 코드표 만들기 예제 with Go (0) | 2012.06.25 |
---|---|
진법(radix) 표 만들기 예제 with Go (0) | 2012.06.25 |
황금비율(golden ratio) 구하기 with Go (0) | 2012.06.20 |
Go 프로그램 언어로 긴 자리 정수 계산하기 (0) | 2012.06.18 |
현재 시각 알아내기 with Go (0) | 2012.06.17 |