# Convert hexadecimal to decimal

**URL:** <https://discuss.ocaml.org/t/convert-hexadecimal-to-decimal/396>\
**Category:** Learning\
**Created:** [June 12, 2017, 11:48am UTC](https://discuss.ocaml.org/t/convert-hexadecimal-to-decimal/396 "2017-06-12T11:48:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jonathandoyle](https://avatars.discourse-cdn.com/v4/letter/j/a3d4f5/32.png) [@jonathandoyle](https://discuss.ocaml.org/u/jonathandoyle)\
**Post date:** [June 12, 2017, 11:48am UTC](https://discuss.ocaml.org/t/convert-hexadecimal-to-decimal/396/1 "2017-06-12T11:48:05Z")

</div>

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.

```ocaml
 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);;

```

---

<div class="post-metadata">

**Author:** ![zozozo](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/zozozo/32/59_2.png) [@zozozo](https://discuss.ocaml.org/u/zozozo)\
**Post date:** [June 12, 2017, 11:54am UTC](https://discuss.ocaml.org/t/convert-hexadecimal-to-decimal/396/2 "2017-06-12T11:54:47Z")

</div>

You can print an int in hexadecimal notation using the `Printf` module

```
 # Printf.printf "0x%x" 12345;;
 0x3039- : unit = ()

```

Also, the `int_of_string` function recognizes hexadecimal notation:

```
# int_of_string "0x3039";;
- : int = 12345

```

If your input string is missing the hexadecimal prefix, you can always do : `int_of_string ("0x" ^ hexadecimal_string)`

---

<div class="post-metadata">

**Author:** ![jonathandoyle](https://avatars.discourse-cdn.com/v4/letter/j/a3d4f5/32.png) [@jonathandoyle](https://discuss.ocaml.org/u/jonathandoyle)\
**Post date:** [June 12, 2017, 12:00pm UTC](https://discuss.ocaml.org/t/convert-hexadecimal-to-decimal/396/3 "2017-06-12T12:00:04Z")

</div>

Thank you! The fact that int\_of\_string recognizes hexadecimal notation is very pleasant.

---

<div class="post-metadata">

**Author:** ![dbuenzli](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dbuenzli/32/18_2.png) [@dbuenzli](https://discuss.ocaml.org/u/dbuenzli)\
**Post date:** [June 12, 2017, 12:28pm UTC](https://discuss.ocaml.org/t/convert-hexadecimal-to-decimal/396/4 "2017-06-12T12:28:51Z")

</div>

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`):

```ocaml
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

```

---

<div class="post-metadata">

**Author:** ![dra27](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dra27/32/5294_2.png) [@dra27](https://discuss.ocaml.org/u/dra27)\
**Post date:** [June 12, 2017, 3:00pm UTC](https://discuss.ocaml.org/t/convert-hexadecimal-to-decimal/396/5 "2017-06-12T15:00:04Z")

</div>

You can also do this with Scanf:

```ocaml
let int_of_hex s =
  try
    Scan.sscanf s "%x%!" (fun x -> x)
  with Scanf.Scan_failure ->
    raise (* Something *)

```
