Charles Haro
Charles Haro

Reputation: 1886

ocaml looking at a specific digit of an int

I am writing an ocaml program and I can't figure out how to look at specific digits of an int

so say for example we have

let a = 405;;

I want to be able to look at the first digit, 4, or the second one, 0. How can I accomplish this? I was thinking of turning it into a string and looking at the chars, but I feel like there should be another way of doing it.

Upvotes: 2

Views: 5140

Answers (3)

Be Chiller Too
Be Chiller Too

Reputation: 2910

I'm adding a new answer because @pad's solution discards leading '0'. I'm proposing a solution that keeps all leading zeroes, useful if you want to parse phone numbers for instance.

let digits s = 
    let rec aux n nb_chars accu = match n with
        | 0 -> (if nb_chars=0 then accu else (aux 0 (nb_chars-1) (0::accu)))
        | _ -> aux (n/10) (nb_chars - 1) (n mod 10::accu)
        in
    let rec init_list = function
        | 0 -> []
        | n -> 0 :: (init_list (n-1))
        in
    if s=(String.make (String.length s) '0')
    then (init_list (String.length s))
    else aux (int_of_string s) (String.length s) [] ;;

Upvotes: 0

pad
pad

Reputation: 41290

You can write a recursive function to extract all digits from a number:

(* Assuming n is a non-negative number *)
let digits n =
    let rec loop n acc =
        if n = 0 then acc
        else loop (n/10) (n mod 10::acc) in
    match n with
    | 0 -> [0]
    | _ -> loop n []

Once you have a list of digits

# digits 405;;
- : int list = [4; 0; 5]

you can get any digit by using some List functions.

Upvotes: 5

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66803

(I'd say this is a general programming problem, not an OCaml problem.)

To get digit k numbered from 0 at the right, you divide (/) by the kth power of 10, then take the result mod 10.

Numbering digits from the left makes this problem harder. If you have to do that, you'll need to know the number of digits the number has, which you can get from the log base 10.

It might be perfectly fine to convert to a string (or, as pad suggests, to a list of digits). This basically does all the divides and mods for all the digits in order. If you're not doing a lot of these conversions, it will be plenty fast enough (IMHO).

Upvotes: 4

Related Questions