컴퓨터 프로그래밍에서 꼭 알아두어야 할 주요 진법은 당연히 10진법, 2진법, 8진법, 16진법이다.
다음은  0 에서 15 까지의 정수를 10진법, 2진법, 8진법, 16진법의 표로 만들어 보여주는 OCaml 소스 코드이다. 진법 변환에 필요한 함수

        int = atoi string radix           (즉, atoi :: string -> int -> int )
        string = itoa number radix    (즉, itoa :: int -> int -> string )

를 OCaml 코드로 자체 작성하여 사용하였다.

(아래의 소스는 Python 소스를 F# 소스로 일대일 변환 수정하고, 또 F# 소스를 OCaml 소스로 바꾼 것이라서 명령형 언어 특징을 위주로 작성되어 있다. 그래서 함수형 언어의 관점으로 보면 사이드 이팩트가 많아 난잡하게 보이는 소스이다.)

  1. (*
  2.  *  Filename: makeRadixTable.ml
  3.  *            Show the radix table with 10-, 2-, 8-, 16-radices.
  4.  *
  5.  *  Execute: ocaml makeRadixTable.ml
  6.  *
  7.  *   Or
  8.  *
  9.  *  Compile: ocamlc -o makeRadixTable.exe makeRadixTable.ml
  10.  *  Execute: makeRadixTable
  11.  *
  12.  *      Date:  2013. 1. 29.
  13.  *    Author:  pkim __AT__scripts.pe.kr
  14.  *)
  15. exception RuntimeError of string
  16. exception ValueError of string
  17. open Printf ;;
  18. let println s = printf "%s\n" s  ;;
  19. let print s =  printf "%s" s  ;;
  20. let printUsage dummy =
  21.     println "Usage: makeRadixTable" ;
  22.     println "Show the radix table with 10-, 2-, 8-, 16-radices."  ;;
  23. let split_char sep str =
  24.   let rec indices acc i =
  25.     try
  26.       let i = succ(String.index_from str i sep) in
  27.       indices (i::acc) i
  28.     with Not_found ->
  29.       (String.length str + 1) :: acc
  30.   in
  31.   let is = indices [0] 0 in
  32.   let rec aux acc = function
  33.     | last::start::tl ->
  34.         let w = String.sub str start (last-start-1) in
  35.         aux (w::acc) (start::tl)
  36.     | _ -> acc
  37.   in
  38.   aux [] is ;;
  39. let sBASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"  ;;
  40. let rec sdup str n =
  41.         match n with
  42.         | 0 -> ""
  43.         | k when k > 0 -> str ^ (sdup str (n - 1))
  44.         | _ -> ""
  45. let contains s1 s2 =
  46.   try
  47.     let len = String.length s2 in
  48.     for i = 0 to (String.length s1) - len do
  49.       if String.sub s1 i len = s2 then raise Exit
  50.     done;
  51.     false
  52.   with Exit -> true ;;
  53. let join list sep =
  54.     let rec join' list acc =
  55.         match list with
  56.             | [] -> ""
  57.             | [single] -> single
  58.             | one::[two] ->
  59.                         if acc = "" then one ^ sep ^ two
  60.                                     else acc ^ one ^ sep ^ two
  61.             | first::others -> join' others (acc ^ first ^ ", ")
  62.                                         in
  63.                                         join' list "" ;;
  64. let str_reverse str =
        let len = String.length str in
  65.     let res = String.create len in
  66.     for i = 0 to pred len do
  67.         let j = pred len - i in
  68.         res.[i] <- str.[j]
  69.     done;
  70.     res ;;
  71. let itoa num radix =
  72.    let isNegative = ref false in
  73.    let num1 = num + 0 in
  74.    let numx = ref num1 in
  75.    if num < 0 then begin
  76.       isNegative := true ;
  77.       numx := (-num)
  78.    end ;
  79.    let nnumx = !numx in
  80.    let q1 = nnumx in
  81.    let q = ref q1 in
  82.    let r = ref 0 in
  83.    let slen = ref 1 in
  84.    while (!q >= radix) do
  85.        r := !q mod radix ;
  86.        q := !q / radix ;
  87.        slen := !slen + 1
  88.    done ;
  89.    let sslen = !slen in
  90.    let str = String.create sslen in
  91.    let p1 = nnumx in
  92.    let p = ref p1 in
  93.    for i = 0 to sslen - 1 do
  94.        r := !p mod radix ;
  95.        p := !p / radix ;
  96.        str.[i] <- sBASE36.[!r]
  97.    done ;
  98.    let str2 = str_reverse str in
  99.    str2;;
  100. let atoi s radix =
  101.     let ret = ref 0 in
  102.     let isNegative = ref false in
  103.     let len = String.length s in
  104.     let valx = ref 0 in
  105.     let c1 = s.[0] in
  106.     let c = ref c1 in
  107.     if !c = '-' then 
  108.        isNegative := true
  109.     else if (!c >= '0' && !c <= '9') then
  110.         ret := (int_of_char !c) - (int_of_char '0')
  111.     else if (!c >= 'A' && !c <= 'Z') then
  112.         ret := (int_of_char !c) - (int_of_char 'A') + 10
  113.     else if (!c >= 'a' && !c <= 'z') then
  114.         ret := (int_of_char !c) - (int_of_char 'a') + 10 ;
  115.     if (!ret >= radix) then
  116.         raise (ValueError (sprintf "Can not read \"%s\" (as radix %d): '%c' is invalid." s radix !c ) ) ;
  117.     for i = 1 to len - 1 do
  118.         c := s.[i] ;
  119.         ret := (!ret)*radix  ;
  120.         if (!c >= '0' && !c <= '9') then
  121.             valx := int_of_char !c - int_of_char '0' 
  122.         else if (!c >= 'A' && !c <= 'Z') then
  123.             valx := int_of_char !c - int_of_char 'A' + 10
  124.         else if (!c >= 'a' && !c <= 'z') then
  125.             valx := int_of_char !c - int_of_char 'a' + 10 ;
  126.         if (!valx >= radix) then 
                raise (ValueError (sprintf "Can not read \"%s\" (as radix %d): '%c' is invalid." s radix !c ) ) ;
  127.         ret := (!ret) + (!valx)
  128.     done;
  129.     if (!isNegative) then
  130.         ret := (-(!ret) ) ;
  131.     !ret ;;
  132. let makeTable() =
  133.     let sbuf = "" in
  134.     let sbuf = sbuf ^ (sdup "+-------" 4) in
  135.     let sbuf = sbuf ^ "+" in
  136.     println sbuf ;
  137.     let sbuf = "|  Dec" in
  138.     let sbuf = sbuf ^  "\t|   Bin" in
  139.     let sbuf = sbuf ^  "\t|  Oct" in
  140.     let sbuf = sbuf ^  "\t|  Hex  |" in
  141.     println sbuf ;
  142.     let sbuf = ""  in
  143.     let sbuf = sbuf ^ (sdup "+-------" 4) in
  144.     let sbuf = sbuf ^  "+" in
  145.     println sbuf ;
  146.     for i = 0 to (16-1) do
  147.         let sbuf = sprintf "|   %2d" i in
  148.         let abuf = itoa i 2  in
  149.         let tbuf = sprintf "\t|  %4s" abuf   in
  150.         let sbuf = sbuf ^ tbuf   in
  151.         let abuf = itoa i 8    in
  152.         let tbuf = sprintf "\t|   %2s" abuf    in
  153.         let sbuf = sbuf ^ tbuf    in
  154.         let abuf = itoa i 16    in
  155.         let tbuf = sprintf "\t|    %-2s |"  abuf    in
  156.         let sbuf = sbuf ^  tbuf    in
  157.         println sbuf
  158.     done ;
  159.     let sbuf = "" in
  160.     let sbuf = sbuf ^ (sdup  "+-------" 4) in
  161.     let sbuf = sbuf ^  "+" in
  162.     println sbuf ;
  163.     "" ;;
  164. let main() =
  165.     let cmdArgs = Sys.argv in
  166.     if (Array.length cmdArgs > 1 && "-h" = cmdArgs.(1)) then begin
  167.         printUsage() ;
  168.         exit(1)
  169.     end ;
  170.     makeTable() ;;
  171. main()

 


실행 결과:

+-------+-------+-------+-------+ | Dec | Bin | Oct | Hex | +-------+-------+-------+-------+ | 0 | 0 | 0 | 0 | | 1 | 1 | 1 | 1 | | 2 | 10 | 2 | 2 | | 3 | 11 | 3 | 3 | | 4 | 100 | 4 | 4 | | 5 | 101 | 5 | 5 | | 6 | 110 | 6 | 6 | | 7 | 111 | 7 | 7 | | 8 | 1000 | 10 | 8 | | 9 | 1001 | 11 | 9 | | 10 | 1010 | 12 | A | | 11 | 1011 | 13 | B | | 12 | 1100 | 14 | C | | 13 | 1101 | 15 | D | | 14 | 1110 | 16 | E | | 15 | 1111 | 17 | F | +-------+-------+-------+-------+

 

Posted by Scripter
,