Non-decimal radices/Convert: Difference between revisions

support 0, fix non-exhaustive matching, use modern API
(→‎{{header|Quackery}}: rewrote to match task requirements)
(support 0, fix non-exhaustive matching, use modern API)
Line 2,524:
- : int = 26
 
A real base conversion exampleimplementation: {{trans|Haskell}}
<syntaxhighlight lang="ocaml">let to_basebasen_of_int b vn : string =
let tab = "0123456789abcdefghijklmnopqrstuvwxyz" in
let rec aux x l =
if x a< b
then tab.[x] :: l
else aux (x / b) (tab.[x mod b] :: l)
in
String.of_seq (List.to_seq (aux n []))
 
let basen_to_int b ds : int =
<syntaxhighlight lang="ocaml">let to_base b v =
let recof_sym to_base' a vc =
ifint_of_char vc =- 0match thenc with
| '0' .. '9' -> int_of_char c - int_of_char '0'
a
| 'a' .. 'z' -> int_of_char c - int_of_char 'a' +- 10
else
| to_base'A' (v.. mod'Z' b-> ::int_of_char a) (v'A' /- b)10
| _ -> invalid_arg "unkown digit"
in
ListString.fold_left (fun n kd -> n * b + kof_sym d) 0 ds</syntaxhighlight>
to_base' [] v
 
let from_base b ds =
List.fold_left (fun n k -> n * b + k) 0 ds
 
let to_alpha_digit n =
if n < 10 then
char_of_int (n + int_of_char '0')
else
char_of_int (n + int_of_char 'a' - 10)
 
let to_alpha_digits ds =
let buf = Buffer.create (List.length ds) in
List.iter (fun i -> Buffer.add_char buf (to_alpha_digit i)) ds;
Buffer.contents buf
 
let from_alpha_digit c = match c with
'0'..'9' -> int_of_char c - int_of_char '0'
| 'A'..'Z' -> int_of_char c - int_of_char 'A' + 10
| 'a'..'z' -> int_of_char c - int_of_char 'a' + 10
 
let from_alpha_digits s =
let result = ref [] in
String.iter (fun c -> result := from_alpha_digit c :: !result) s;
List.rev !result</syntaxhighlight>
 
Example:
 
<pre>
# to_alpha_digits (to_basebasen_of_int 16 42)26;;
- : string = "2a1a"
# from_basebasen_to_int 16 (from_alpha_digits "2a1a");;
- : int = 4226
</pre>
 
559

edits