# `Feel.Builtin.Number`
[🔗](https://github.com/FeeJai/BDM/blob/feel-v0.1.0/apps/feel/lib/feel/builtin/number.ex#L1)

The numeric functions of FEEL (DMN 1.6, section 10.3.4.5, Table 77).

## What is written (D-79)

All fourteen.

| Call | Result |
| ---- | ------ |
| `decimal(n, scale)` | `n` with `scale` digits after the point, rounded half to even |
| `floor(n)`, `floor(n, scale)` | toward negative infinity |
| `ceiling(n)`, `ceiling(n, scale)` | toward positive infinity |
| `round up(n)`, `round up(n, scale)` | away from zero |
| `round down(n)`, `round down(n, scale)` | toward zero |
| `round half up(n)`, `round half up(n, scale)` | to the nearest, a tie away from zero |
| `round half down(n)`, `round half down(n, scale)` | to the nearest, a tie toward zero |
| `abs(n)` | the absolute value of a number, or of a duration of either kind |
| `modulo(dividend, divisor)` | `dividend - divisor * floor(dividend / divisor)`, which has the sign of the divisor |
| `sqrt(number)` | the square root, `null` for a negative number |
| `log(number)` | the natural logarithm, `null` unless the number is positive |
| `exp(number)` | e raised to the number |
| `odd(number)`, `even(number)` | the parity of a whole number, `null` for one with a fraction |

**The rounding functions** share one rule (the examples of the specification force the mode of each,
section 6 of the notes): the result has exactly `scale` digits after the point, so `decimal(1, 2)` is
`1.00`, and a negative scale rounds to tens, hundreds and so on (`decimal(1234, -2)` is `1.2E+3`). The
scale is a whole number: a fraction is cut off (section 10.3.2.9.4), and it has to be in `-6111..6176`.
A result with more than 34 digits is `null` (Table 60); a number that has no more digits after the
point than the scale is not rounded, and is written with the zeros up to the scale when they fit (so
`decimal(1, 2)` is `1.00` and `round up(5.5, 6176)` is `5.5`). Without a scale it is 0, and `floor(n: x)` is
`floor(x)`, not `floor(x, null)`: a call with named arguments is for the signature that has exactly those
names (notes, AE-37), while `floor(x, null)` is `null`.

**`modulo`** is worked out on the integers behind the two numbers, so it is exact whatever their size:
`modulo(10.1, 4.5)` is `1.1`, `modulo(-12, 5)` is `3` and `modulo(12, -5)` is `-3`. A divisor of zero is out
of the domain, and so is a rest that needs more than 34 digits (`modulo(-1E-6176, 7)`, whose rest is 7 less 1E-6176); the
zeros at the end of a rest that two operands written with different scales leave are not digits it needs.

A `null` argument, and one of another kind than the function takes, is out of its domain: the result is
`null`, with an `:argument_out_of_domain` error, as for the conversion functions (the TCK flags
`abs(null)`, `floor(null, 1)` and `modulo(10, null)` as errors). A list of one number is that number
(section 10.3.2.9.4).

# `functions`

```elixir
@spec functions() :: [Feel.Builtin.Function.t()]
```

The functions of this module that are written, as `Feel.Builtin.Function`s.

# `names`

```elixir
@spec names() :: [Feel.Name.t()]
```

Returns the canonical names of the functions of this module, sorted.

    iex> "round half even" in Feel.Builtin.Number.names()
    false
    iex> "round half up" in Feel.Builtin.Number.names()
    true

---

*Consult [api-reference.md](api-reference.md) for complete listing*
