I'm going to take a break from talking about Elixir projects and applications to go over a few more functions in the `Kernel`

module. I'm going to cover two more categories of functions: binary functions and math functions.

## Binary Functions

These are the `Kernel`

module functions that deal with binaries.

### Kernel.<>/2

The `Kernel.<>/2`

function corresponds to the binary concatenation operator `<>`

. It takes in two binaries and returns the two binaries concatenated together. In practice, the binaries will mostly be strings, but any binaries will work. You're most likely going to be using the operator rather than calling the function directly, but it's there if you need to pass it into a higher-order function.

```
iex> Kernel.<>("My name is ", "Ursula")
"My name is Ursula"
iex> "My name is " <> "Ursula"
"My name is Ursula"
iex> Kernel.<>(<<4, 3, 64>>, <<3, 0, 12, 43>>)
<<4, 3, 64, 3, 0, 12, 43>>
iex> Enum.reduce(["a", "b", "c", "d", "e"], "", &Kernel.<>/2)
"edcba"
```

### Kernel.binary_part/3

The `Kernel.binary_part/3`

function extracts a section of a binary. It's like a substring operation, but it can be used with any binary. The first parameter is the binary, the second parameter is the starting index, and the third parameter is the length of the section to be extracted.

If either the start or length parameters go beyond the bounds of the binary, an `ArgumentError`

is thrown.

This function can be used in a guard clause.

There is also a `String.slice/3`

function that is very similar to this one. The difference is that `String.slice/3`

operates on characters (code points) whereas `Kernel.binary_part/3`

operates on bytes. It's possible to split a binary in the middle of a multi-byte UTF-8-encoded character using `Kernel.binary_part/3`

, but that would not be possible with `String.slice/3`

.

```
iex> binary_part(<<1, 2, 3, 4, 5, 6, 7, 8>>, 3, 4)
<<4, 5, 6, 7>>
iex> binary_part(<<1, 2, 3, 4, 5, 6, 7, 8>>, 0, 0)
""
iex> binary_part(<<1, 2, 3, 4, 5, 6, 7, 8>>, 0, 1)
<<1>>
iex> binary_part(<<1, 2, 3, 4, 5, 6, 7, 8>>, 10, 1)
** (ArgumentError) argument error
:erlang.binary_part(<<1, 2, 3, 4, 5, 6, 7, 8>>, 10, 1)
iex> binary_part(<<1, 2, 3, 4, 5, 6, 7, 8>>, 5, 10)
** (ArgumentError) argument error
:erlang.binary_part(<<1, 2, 3, 4, 5, 6, 7, 8>>, 5, 10)
iex> binary_part("string", 0, 1)
"s"
iex> binary_part("string", 2, 1)
"r"
```

### Kernel.bit_size/1

The `Kernel.bit_size/1`

function returns the number of bits in a binary.

This function can be used in a guard clause.

```
iex> bit_size(<<3, 9, 134, 12, 22>>)
40
iex> bit_size(<<3, 9, 134, 12, 22, 9>>)
48
iex> bit_size(<<3, 9, 22, 9>>)
32
iex> bit_size(<<7>>)
8
iex> bit_size(<<>>)
0
iex> bit_size("This is a string")
128
```

### Kernel.byte_size/1

The `Kernel.byte_size/1`

function returns the number of bytes in a binary. If the number of bits is not divisible by 8, which can be the case if the binary is a bitstring, it will be rounded up.

This function can be used in a guard clause.

```
iex> byte_size(<<3, 9, 134, 12, 22>>)
5
iex> byte_size(<<3, 9, 134, 12, 22, 9>>)
6
iex> byte_size(<<3, 9, 22, 9>>)
4
iex> byte_size(<<7>>)
1
iex> byte_size(<<>>)
0
iex> byte_size("This is a string")
16
#This is 26 bits, so is rounded up to 32 bits (4 bytes)
iex> byte_size(<<3, 4::6, 6::12>>)
4
#This is 6 bits, so is rounded up to 8 bits (1 byte)
iex> byte_size(<<3::6>>)
1
```

## Math Functions

These are various functions in the `Kernel`

module functions that deal with numbers. I've grouped them together and called them "math" functions, but that's just my personal labelling in an attempt to group all the functions in the `Kernel`

module.

### Kernel.abs/1

The `Kernel.abs/1`

returns the absolute value of a number, which can be an integer or float.

This function can be used in a guard clause.

```
iex> abs(-5)
5
iex> abs(-1)
1
iex> abs(0)
0
iex> abs(2)
2
iex> abs(2.3)
2.3
iex> abs(-2.875)
2.875
```

### Kernel.div/2

The `Kernel.div/2`

function performs integer division. Any remainder is discarded. This has the effect of rounding down for positive numbers and rounding up for negative numbers (rounding towards 0). Division by 0 will of course result in an error. Only integers can be passed as parameters.

This is works just like division in C++ or C# when two integers are involved.

This function can be used in a guard clause.

```
iex> div(8, 4)
2
iex> div(8, 3)
2
iex> div(8, 2)
4
iex> div(-8, 4)
-2
iex> div(-8, 3)
-2
iex> div(10, 3)
3
iex> div(0, 3)
0
iex> div(3, 0)
** (ArithmeticError) bad argument in arithmetic expression: div(3, 0)
:erlang.div(3, 0)
iex> div(2.3, 1.2)
** (ArithmeticError) bad argument in arithmetic expression: div(2.3, 1.2)
:erlang.div(2.3, 1.2)
```

### Kernel.rem/2

The `Kernel.rem/2`

function gives us the remainder after integer division has been performed. It's equivalent to the modulo operator `%`

in Javascript and C#. This particular function has already been used a lot in prior examples.

If we are dividing by a number, then the remainder must fall in the range 0 to number - 1. If we divide by two, we can look at the remainder to determine if a number is even or odd.

This function can be used in a guard clause.

```
iex> rem(8, 2)
0
iex> rem(8, 3)
2
iex> rem(8, 4)
0
iex> rem(8, 5)
3
iex> rem(10, 3)
1
iex> rem(10, 2)
0
iex> rem(11, 2)
1
iex> rem(12, 2)
0
```

### Kernel.round/1

The `Kernel.round/1`

function rounds a number to the nearest integer.

This function can be used in a guard clause.

```
iex> round(1)
1
iex> round(1.1)
1
iex> round(1.4)
1
iex> round(1.5)
2
iex> round(1.9)
2
iex> round(2.5)
3
iex> round(-2.5)
-3
iex> round(-2.4)
-2
iex> round(0.4999999)
0
iex> round(0.9999999)
1
```

### Kernel.trunc/1

The `Kernel.trunc/1`

function truncates a number. That means that the non-integer part of the number is discarded and the integer part is returned.

This function can be used in a guard clause.

```
iex> trunc(3)
3
iex> trunc(3.14)
3
iex> trunc(3.9)
3
iex> trunc(-2)
-2
iex> trunc(-2.3)
-2
iex> trunc(-2.9)
-2
```

### Kernel.floor/1

The `Kernel.floor/1`

function always rounds a number down to the nearest integer, unless the number is an integer already. In the words of the documentation, it returns "the largest integer not greater than the number passed to the function". This is the same behavior as `Kernel.trunc/1`

for positive numbers, but it differs for negative numbers.

This function can be used in a guard clause.

```
iex> floor(3)
3
iex> floor(3.14)
3
iex> floor(3.9)
3
iex> floor(0)
0
iex> floor(-2)
-2
iex> floor(-2.3)
-3
iex> floor(-2.9)
-3
```

### Kernel.ceil/1

The `Kernel.ceil/1`

function is the opposite of `Kernel.floor/1`

. It always rounds the number up to the next highest integer, unless the number is an integer already. In the words of the documentation, it returns "the smallest integer greater than the number passed to the function". This is the same behavior as `Kernel.trunc/1`

for negative numbers, but it differs for positive numbers.

```
iex> ceil(3)
3
iex> ceil(3.14)
4
iex> ceil(3.9)
4
iex> ceil(0)
0
iex> ceil(-2)
-2
iex> ceil(-2.3)
-2
iex> ceil(-2.9)
-2
```

## Conclusion

That's it for today. We still have a lot of functions remaining in the Kernel module, and we'll eventually cover them all. No hurry, they'll be there waiting for us