다음은  대화형 모드(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진법 까지이다.
    



  1. /*
  2.  *  Filename: convertRadix.go
  3.  *
  4.  *            Convert radix in a interactive mode.
  5.  *
  6.  *  Execute: go run convertRadix.go
  7.  *
  8.  *  or
  9.  *
  10.  *  Compile: go build convertRadix.go
  11.  *  Execute: ./convertRadix
  12.  *
  13.  *      Date:  2012/06/25
  14.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  15.  */
  16. package main
  17. import (
  18.     "fmt"
  19.     "bufio"
  20.     "os"
  21.     "strings"
  22. )   
  23. type _TOKEN struct {
  24.     a string
  25.     b string
  26. }
  27. func println(s string) {
  28.     fmt.Printf("%s\n", s)
  29. }
  30. func print(s string) { 
  31.     fmt.Printf("%s", s)
  32. }
  33. func printUsage() {
  34.     println("Usage: convertRadix")
  35.     println("Convert radix in an interactive mode, where the maximum radix is 36.")
  36. }
  37. func printAbout() {
  38.     println("    About: Convert radix in a interactive mode.")
  39. }
  40. func printMainMenu() {
  41.     println("  Command: (S)etup radix, (A)bout, (Q)uit or E(x)it")
  42. }
  43. func printMainPrompt() {
  44.     print("  Prompt> ")
  45. }
  46. func printSubMenu(srcRadix int, destRadix int) {
  47.     var sbuf string
  48.     fmt.Sprintf(sbuf, "    Convert Radix_%d to Radix_%d", srcRadix, destRadix);
  49.     println(sbuf);
  50.     println("    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit");
  51. }
  52. func printSubPrompt() {
  53.     print("    Input Value>> ");
  54. }
  55. func convertItoA(num int64, radix int) (ret string) {
  56.     var BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  57.     var tmp string
  58.     var arr string
  59.     var q, r int64
  60.     var i, n int
  61.     var isNegative bool = false
  62.     if num < 0 {
  63.         isNegative = true
  64.         num = -num
  65.     }
  66.     arr = ""
  67.     q = num
  68.     r = 0
  69.     for q >= int64(radix) {
  70.         r = q % int64(radix)
  71.         q = q / int64(radix)
  72.         tmp = BASE36[r:r+1]
  73.         arr += tmp
  74.     }
  75.     tmp = BASE36[q:q+1]
  76.     arr += tmp
  77.     if isNegative {
  78.         arr += "-"
  79.     }
  80.     n = len(arr)
  81.     for i = 0; i < n; i++ {
  82.         ret += arr[n - i - 1:n-i]
  83.     }
  84.     return ret
  85. }
  86. func convertAtoI(str string, radix int) (ret int64) {
  87.     var isNegative bool = false
  88.     var len int = len(str)
  89.     var c byte
  90.     var i int
  91.     var val int64
  92.     c = str[0]
  93.     if c == '-' {
  94.         isNegative = true
  95.     } else if c >= '0' && c <= '9' {
  96.         ret = int64(c) - int64('0')
  97.     } else if c >= 'A' && c <= 'Z' {
  98.         ret = int64(c - 'A') + 10
  99.     } else if c >= 'a' && c <= 'z' {
  100.         ret = int64(c - 'a') + 10
  101.     }
  102.     if ret >= int64(radix) {
  103.         println("        Invalid character!")
  104.         return ret
  105.     }
  106.     for i = 1; i < len; i++ {
  107.         c = str[i]
  108.         ret *= int64(radix)
  109.         if c >= '0' && c <= '9' {
  110.             val = int64(c - '0')
  111.         } else if c >= 'A' && c <= 'Z' {
  112.             val = int64(c - 'A') + 10
  113.         } else if c >= 'a' && c <= 'z' {
  114.             val = int64(c - 'a') + 10
  115.         }
  116.         if val >= int64(radix) {
  117.             println("        Invalid character!")
  118.             return ret
  119.         }
  120.         ret += val
  121.     }
  122.     if isNegative {
  123.         ret = -ret
  124.     }
  125.     return ret
  126. }
  127. func convertRadix(s string, srcRdx  int, destRdx int) (ret string) {
  128.     var val int64
  129.     val = convertAtoI(s, srcRdx)
  130.     ret = convertItoA(val, destRdx)
  131.     return ret
  132. }
  133. func readLine() (data string) {
  134.     fmt.Scanf(data, "%s") //
  135.     return data
  136. }
  137. func readTwo() (token _TOKEN) { 
  138.     token.a = ""
  139.     token.b = ""
  140.     fmt.Scanf("%s %s", &token.a, &token.b)    // call twice, is It a bug?
  141.     fmt.Scanf("%s %s", &token.a, &token.b)    // call twice, is It a bug?
  142.     return token
  143. }
  144. func tokenize(ptoken _TOKEN, line string, c byte) {
  145.     var i int
  146.     var from, to int
  147.     i = 0
  148.     for line[i] != c {
  149.         i += 1
  150.     }
  151.     from = i
  152.     for line[i] == c {
  153.         i += 1
  154.     }
  155.     to = i
  156.     ptoken.a = line[0: to - from]
  157.     for line[i] != c {
  158.         i += 1
  159.     }
  160.     from = i
  161.     for line[i] == c {
  162.         i += 1
  163.     }
  164.     to = i
  165.     ptoken.b = line[0: to - from]
  166. }
  167. func doConvert(srcRadix int,destRadix int) {
  168.     var sbuf string
  169.     var cmd string
  170.     var srcStr string
  171.     var destStr string
  172.     println("")
  173.     printSubMenu(srcRadix, destRadix)
  174.     for {
  175.         printSubPrompt()
  176.         cmd = ""
  177.         fmt.Scanf("%s", &cmd)        // call twice, is It a bug?
  178.         for cmd == "" {
  179.             fmt.Scanf("%s", &cmd)       // call twice, is It a bug?
  180.         }
  181.         if cmd == "main()" {
  182.             return
  183.         } else if cmd == "exit()" || cmd == "quit()" {
  184.             os.Exit(0)
  185.         } '
  186.         srcStr = cmd
  187.         destStr = convertRadix(srcStr, srcRadix, destRadix)
  188.         sbuf = fmt.Sprintf("        ( %s )_%d   --->   ( %s )_%d", srcStr, srcRadix, destStr, destRadix);
  189.         println(sbuf)
  190.         println("")
  191.     }
  192. }
  193. func doStart() { 
  194.     var srcRadix int = 10
  195.     var destRadix int = 10 
  196.     var st _TOKEN
  197.     var onlyOnce bool = true
  198.     for {
  199.         println("")
  200.         if onlyOnce {
  201.             println("  The supported maximum radix is 36.")
  202.             onlyOnce = false
  203.         }
  204.         printMainMenu()
  205.         printMainPrompt()
  206.         var cmd string = ""
  207.         fmt.Scanf("%s", &cmd)    // call twice, is It a bug?
  208.         fmt.Scanf("%s", &cmd)    // call twice, is It a bug?
  209.         if  len(cmd) == 1&& strings.IndexAny("qQxX", cmd) >= 0 {
  210.             os.Exit(0)
  211.         }  else if len(cmd) == 1&& strings.IndexAny("aA", cmd) >= 0 {
  212.             printAbout()
  213.         }  else if len(cmd) == 1&& strings.IndexAny("sS", cmd) >= 0 {
  214.             print("  Input the source and target radices (say, 16 2): ") 
  215.             st = readTwo()
  216.             srcRadix = int(convertAtoI(st.a, 10))
  217.             destRadix = int(convertAtoI(st.b, 10))
  218.             doConvert(srcRadix, destRadix)
  219.         }
  220.     }
  221. }
  222. func waitCommand(str string) string {
  223.         print(str)
  224.         reader := bufio.NewReader(os.Stdin)
  225.         input, _ := reader.ReadString('\n')
  226.         if len(input) > 0 && input[len(input) -1] == '\n' {
  227.             input = input[0:len(input) -1]
  228.         }
  229.         if len(input) > 0 && input[len(input) -1] == '\r' {
  230.             input = input[0:len(input) -1]
  231.         }
  232.         return input
  233. }
  234. func main() {
  235.     if len(os.Args) > 1 &&  os.Args[1] == "-h" {
  236.         printUsage()
  237.         return
  238.     }
  239.     doStart()
  240. }




실행> 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()



Posted by Scripter
,