# `Errow.Numeric`
[🔗](https://github.com/kuku/errow/blob/v0.1.0/lib/errow/numeric.ex#L1)

An immutable, continuous-memory numerical array implementing the Apache Arrow Primitive columnar format.

Under the hood, data is organized in two buffers:
  1. **Data buffer** (`data`): a continuous binary of fixed-width numbers in little-endian.
  2. **Validity bitmap** (`validity`): a bitstring tracking null (`nil`) values (1 bit per element).

## Supported Types
* Signed Integers: `:s8, :s16, :s32, :s64, :s128, :s256`
* Unsigned Integers: `:u8, :u16, :u32, :u64, :u128, :u256`
* Floating Point: `:f32, :f64`

Notice that `:s128`, `:u128`, `:s256`, and `:u256` are natively supported in little-endian binary format,
mapping directly to Arrow `Decimal128`, `Decimal256`, and `FixedSizeBinary`.

# `numeric_type`

```elixir
@type numeric_type() ::
  :s8
  | :u8
  | :s16
  | :u16
  | :s32
  | :u32
  | :s64
  | :u64
  | :s128
  | :u128
  | :s256
  | :u256
  | :f32
  | :f64
```

# `t`

```elixir
@type t() :: %Errow.Numeric{
  data: binary(),
  item_size: pos_integer(),
  length: non_neg_integer(),
  null_count: non_neg_integer(),
  type: numeric_type(),
  validity: bitstring()
}
```

# `append`

```elixir
@spec append(t(), number() | nil) :: t()
```

Appends a number or `nil` to the array.

# `buffer_byte_size`

```elixir
@spec buffer_byte_size(t()) :: non_neg_integer()
```

Returns the byte size of the continuous data buffer.

# `delete_at`

```elixir
@spec delete_at(t(), integer()) :: t()
```

Deletes the element at index `idx`.

# `fetch`

```elixir
@spec fetch(t(), integer() | Range.t()) :: {:ok, number() | nil | list()} | :error
```

Fetches the element at the given index or a slice specified by a range.
Supports negative indices (e.g. `-1` for the last element).

# `from_list`

```elixir
@spec from_list(Enumerable.t(), numeric_type()) :: t()
```

Builds an `Errow.Numeric` array from a list or enumerable of numbers and optional `nil`s.

# `get`

```elixir
@spec get(t(), integer(), any()) :: number() | nil | any()
```

Gets the value at index `idx` or returns `default` if out of bounds.

# `max`

```elixir
@spec max(t(), keyword()) :: number() | nil
```

Finds the maximum value in the array.

# `mean`

```elixir
@spec mean(t(), keyword()) :: float() | nil
```

Calculates the arithmetic mean (average) of the elements as a float.

# `min`

```elixir
@spec min(t(), keyword()) :: number() | nil
```

Finds the minimum value in the array.

# `min_max`

```elixir
@spec min_max(t(), keyword()) :: {number(), number()} | nil
```

Returns a `{min, max}` tuple in a single pass over the array.

# `new`

```elixir
@spec new(numeric_type()) :: t()
```

Creates a new empty `Errow.Numeric` array of the given type (defaults to `:s64`).

# `null?`

```elixir
@spec null?(t(), integer()) :: boolean()
```

Checks if the value at the given index is null (`nil`).

# `null_count`

```elixir
@spec null_count(t()) :: non_neg_integer()
```

Returns the count of null values.

# `product`

```elixir
@spec product(t(), keyword()) :: number() | nil
```

Calculates the product of elements in the array.
Options:
  * `:skip_nulls` - boolean, defaults to `true`.

# `replace_at`

```elixir
@spec replace_at(t(), integer(), number() | nil) :: t()
```

Replaces the element at the given index with a new number or `nil`.

# `size`

```elixir
@spec size(t()) :: non_neg_integer()
```

Returns the number of elements in the array.

# `sum`

```elixir
@spec sum(t(), keyword()) :: number() | nil
```

Calculates the sum of elements in the array.
Options:
  * `:skip_nulls` - boolean, defaults to `true`.

# `to_list`

```elixir
@spec to_list(t()) :: [number() | nil]
```

Converts the `Errow.Numeric` array into a standard Elixir list.

---

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