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

The FEEL type `number` (DMN 1.6, section 10.3.2.3.1).

A number is a decimal with at most 34 significant digits, as in the IEEE 754
decimal128 format, and it is exact: `0.1 + 0.2` is `0.3`. It is represented as
a `Decimal`. FEEL has no "not a number" and no infinities, so a `Decimal` with
either of those values is not a FEEL number; a result that would be one is
`null` instead.

`value?/1` checks only that a term is a finite decimal. Keeping results within
34 digits and the valid range of exponents is the job of arithmetic. `parse/1`
applies those limits to the text of a number.

# `t`

```elixir
@type t() :: Decimal.t()
```

# `parse`

```elixir
@spec parse(String.t()) :: {:ok, t()} | :error
```

Parses the text of a number, as written by grammar rule 35 of DMN 1.6: an
optional minus sign, digits with an optional fraction, and an optional
exponent.

The scale of the text is kept: `1.50` stays `1.50`. A value with more than 34
significant digits is rounded to 34, half to even. Returns `:error` when the
text is not a number or its exponent is outside the decimal128 range. There is
no negative zero: `-0` is `0`.

    iex> Feel.Value.Number.parse("1.50")
    {:ok, Decimal.new("1.50")}
    iex> Feel.Value.Number.parse("-.5")
    {:ok, Decimal.new("-0.5")}
    iex> Feel.Value.Number.parse("1.2e3")
    {:ok, Decimal.new("1.2E+3")}
    iex> Feel.Value.Number.parse("5.")
    :error
    iex> Feel.Value.Number.parse("1e99999")
    :error

# `round_to_digits`

```elixir
@spec round_to_digits(non_neg_integer(), integer()) :: {non_neg_integer(), integer()}
```

Rounds a coefficient with more than 34 digits to 34, half to even, and returns it with its
exponent. A coefficient of 34 digits or fewer is returned as it is.

    iex> Feel.Value.Number.round_to_digits(12, -1)
    {12, -1}
    iex> Feel.Value.Number.round_to_digits(10 ** 34 + 5, 0)
    {10 ** 33, 1}
    iex> Feel.Value.Number.round_to_digits(10 ** 34 + 15, 0)
    {10 ** 33 + 2, 1}

# `type`

```elixir
@spec type() :: Feel.Type.t()
```

Returns the type descriptor of `number`.

# `value?`

```elixir
@spec value?(term()) :: boolean()
```

Returns `true` for a `Decimal` that is a number of FEEL: finite, with a coefficient of at most 34 digits and an exponent
inside the decimal128 range (`Feel.Runtime.Number.valid?/1`, D-214). A value that a host binds and that is not one is no
number where a value is checked, as arithmetic refuses it.

    iex> Feel.Value.Number.value?(Decimal.new("1.5"))
    true
    iex> Feel.Value.Number.value?(Decimal.new("NaN"))
    false
    iex> Feel.Value.Number.value?(Decimal.new(1, 10_000_000_000_000_000_000_000_000_000_000_000, -34))
    false
    iex> Feel.Value.Number.value?(1.5)
    false

---

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