02 April 2017

*The following post was inspired by the tricks I learned about performing math operations in Elixir while working through the Elixir Exercisms.
I feel like I learned a lot about the nuances of the language while working through the exercises and I highly recommend it!*

The big, key features of Elixir that set it apart among modern languages are its *scalability*, *fault tolerance*, and the *actor model of proccesses*.
You probably aren’t using Elixir in particular for its math capabilities, but that doesn’t mean you won’t be doing math operations in Elixir.
Below is a list (in no particular order) of some of the little things I learned about performing math in Elixir.

- Don’t always divide with
`/`

, use`div/2`

- Don’t forget you have access to Erlang’s stdlib
`:math`

module - You probably don’t want to use
`:math.pow/2`

for large numbers - Erlang’s
`:crypto`

module contains`mod_pow/3`

`/`

, use `div/2`

This is especially true when you want an integer as the result.
By default, dividing with `/`

results in a float:

```
iex> 4 / 2
2.0
```

From here, to get to a integer, you would have to use `trunc/1`

, which cuts off any decimals, or `round/1`

which rounds to the nearest integer:

```
iex> 5 / 2
2.5
iex> trunc(5 / 2)
2
iex> round(5 / 2)
3
```

If you want just the integer (probably because you’ll get the remainder using `rem/2`

), you can just use `div/2`

:

```
iex> div(5, 2)
2
iex> rem(5, 2)
1
```

Personally, while working through the exercisms, I found that I end up using `div/2`

more than diving with `/`

.

`:math`

moduleThis has been a personal difficulty of mine when transitioning my thinking to Elixir.
I always seem to forget that I have access to the whole of the Erlang standard library, which includes a `:math`

module.
Need to find the square root of something or solve a logarithmic expression?
Erlang has a `:math.sqrt/1`

and `:math.log/1`

.

It’s also a good idea to probably expand on this and just try to keep this in mind while working in Elixir.

`:math.pow/2`

for large numbersOne exception I found is that when raising a base number to an exponent, you probably don’t want to use the `:math.pow/2`

function.
This has something to do with how the `:math`

library handles large numbers, and is something that I didn’t dive into to figure out.

```
iex> :math.pow(42, 909)
** (ArithmeticError) bad argument in arithmetic expression
(stdlib) :math.pow(42, 909)
```

Instead, you can easily define your own using two function heads:

```
def pow(base, 1), do: base
def pow(base, exp), do: base * pow(base, exp - 1)
```

This will give you exactly what you want, a really big number.

`:crypto`

module contains `mod_pow/3`

This one comes from the Diffie-Hellmen exercise.
To generate a public key or a shared secret, you need to get the modulus of the result of raising a very large base to a very large exponent.
You can write this out in Elixir and it will happily perform the operation for you (using the previously defined `pow/2`

):

```
def generate_public_key(mod, base, exp), do: rem(pow(base, exp), mod)
```

However, this will choke in calculating a sufficiently large numbers and be catastrophically slow.
Since what we’re working with here is a cryptographic algorithm, we should keep Erlang’s `:crypto`

module in mind.
It contains a `mod_pow/3`

function that can do this for us, and really fast.
The one catch here is that it returns a binary that you have to decode into an unsigned integer.
The bonus here, is that it actually is returning an integer for you, no `round/1`

or `trunc/1`

necessary!

```
def generate_public_key(mod, base, exp) do
:binary.decode_unsigned(:crypto.mod_pow(base, exp, mod))
end
```

I haven’t delved into why it’s so fast exactly, but I assumed it has something to do about it not being worried about intermediate integer representation.

I think the best advice I have to give, both for math and Elixir development in general, is just don’t forget about all of the extra goodies you get from Erlang!

Have an interesting or cool math trick of your own? Comment below or tell me about it on twitter!