In the code below, the int_of_hex function converts a hexadecimal to a decimal. Is there a built-in function that does the same thing ?
I am aware of the 0x syntax, but the naive let int_to_hex hex=0xhex;; is of course incorrect in OCaml).
Perhaps the Printf module can help here.
exception Hexchar_exn of char;;
let int_of_hexchar c=
try List.assoc c
[
('0', 0); ('1', 1); ('2', 2); ('3', 3); ('4', 4); ('5', 5);
('6', 6); ('7', 7); ('8', 8); ('9', 9);
('A', 10); ('B', 11); ('C', 12); ('D', 13); ('E', 14); ('F', 15)
]
with _->raise(Hexchar_exn(c));;
let int_of_hex s=
let n=String.length(s)
and accu=ref(0) in
for i=1 to n do accu:=int_of_hexchar(String.get s (i-1))+16*(!accu) done;
(!accu);;
Except for int_of_string which needs the 0x prefix I don’t think there such a thing in the stdlib.
Depending on what you do allocating a new string on each parse may be a bit too slow. Also in your code I would avoid using an assoc list for that.
Here would be my take on the function (man ascii may help to understand the magic constants of digit_value):
let int_of_hex s =
let digit_value c =
let c = Char.code c in
if c <= 0x2F then raise_notrace Exit else
if c <= 0x39 then c - 48 else
if c <= 0x40 then raise_notrace Exit else
if c <= 0x46 then c - 55 else
if c <= 0x60 then raise_notrace Exit else
if c <= 0x66 then c - 87 else
raise_notrace Exit
in
match s with
| "" -> None
| s ->
let max = String.length s - 1 in
let rec loop i acc = match i > max with
| true -> acc
| false -> loop (i + 1) (acc * 16 + digit_value s.[i])
in
try Some (loop 0 0) with Exit -> None