Elixir: Binary to Decimal
Tags: functional, elixir
Published: 2020-06-08 00:06:51

Hey there DEV.to community!

I've decided to share the codes I write in Elixir and help this beautiful language to grow its community!

In order to implement such a function to convert a binary representation to a decimal number here are the procedures:

First we define a `binary_to_decimal` function to start our recursion:
```elixir
defmodule BinaryToDecimal do
    def binary_to_decimal n do
        digits = Integer.digits n
        sum_up digits, 0
    end
end
```

In this function we create a list of our digits and pass it to the `sum_up` function.

Then we will define two function to use them recursively, one if the passed list is empty so it returns the accumulated data and the other to do the recursion:
```elixir
    def sum_up([], acc), do: acc
    def sum_up list, acc do
        [ head | tail ] = list
        length = Enum.count list
        if head === 1 do
            sum_up tail, acc + (:math.pow(2, length - 1) |> round)
        else
            if head !== 0 do
                raise "Encountered a digit other than 0 or 1"
            else
                sum_up tail, acc
            end
        end
    end
```

Explanation is simple:
1. Using the pattern matching we get the head and the tail of our list, head being the first element and tail the rest.
2. Get the count the length of the list and assign to the `length` variable
3. If the head is equal to 1, call the `sum_up` function by passing the tail as the list and accumulate the current value of `acc` with the result of 2 to the power of length minus 1. (We need to subtract 1 from the length since the last position in a binary representation is 2 to the power of 0 which is equal to 1.)
4. Else we check if head is not equal to 0 so we raise an error defining that a digit other than 0 or 1 has been encountered otherwise call `sum_up` function by passing the tail as the list and the `acc` variable with no change.
5. Finally if the tail is empty the first function will return the accumulation and the job is done.

You can run this function just as simple as this:
```elixir
def run do
        binary_to_decimal 00110010
end
```

And here is the full commented code:
```elixir
defmodule BinaryToDecimal do
    def binary_to_decimal n do
        # Create a list of digits
        digits = Integer.digits n

        # Call the sum_up function with starting accumulation of 0
        sum_up digits, 0
    end

    # Return the accumulation if the first argument is an empty list
    def sum_up([], acc), do: acc

    # A recursive function to accumulate the binary equivalent values
    def sum_up list, acc do
        # Use pattern matching to get the head and tail
        [ head | tail ] = list
        # Get the length of the current list
        length = Enum.count list
        #Check if the current digit in loop (being head) is equal to 1
        if head === 1 do
            # Recursively call sum_up function with tail passed as the list
            # and accumulate 2 to the power of length - 1
            # we need length - 1 since the last place in a binary
            # representation is 0 not 1
            sum_up tail, acc + (:math.pow(2, length - 1) |> round)
        else
            if head !== 0 do
                # Check if head is not equal to 0 and raise and error if so
                raise "Encountered a digit other than 0 or 1"
            else
                # If the digit is equal to 0 just call the sum function
                # and pass tail
                # and acc with no change
                sum_up tail, acc
            end
        end
    end

    def run do
        # Call the binary_to_decimal function to begin
        binary_to_decimal 00110010
    end
end
```

Hope you enjoyed!