mech-math 0.3.3

Math library for the Mech language
Documentation
math/ilogb
===============================================================================

%% Integer base-2 exponent of a floating-point value (element-wise)

1. Usage
-------------------------------------------------------------------------------

```mech:disabled
E := math/ilogb(X)
```

2. Description
-------------------------------------------------------------------------------

Returns the **integer exponent** of each floating-point element of `X` such that:

```
X = m * 2^E   with   m ∈ [1, 2)  (for normal numbers)
```

This is the standard C/libm `ilogb`/`ilogbf` behavior. It does **not** return
`log2(X)`; instead it returns the unbiased exponent as an integer. Works on
scalars, vectors, and matrices of `f32` or `f64`. The output `E` has the same
shape as `X` but contains **integers**.

3. Input
-------------------------------------------------------------------------------

| Argument | Kind                             | Description                                              |
|----------|----------------------------------|----------------------------------------------------------|
| `X`      | `f32`, `f64`, `[float]`, `[[float]]` | Floating-point value(s) to extract the base-2 exponent from. |

4. Output
-------------------------------------------------------------------------------

| Argument | Kind                 | Description                                                |
|----------|----------------------|------------------------------------------------------------|
| `E`      | `i32`, `[i32]`, `[[i32]]` | Integer exponent(s) corresponding to each element of `X`. |

5. Examples
-------------------------------------------------------------------------------

(a) Scalars

```mech:ex1
e1 := math/ilogb(1.0)        // 0   since `1.0 = 1.0 * 2^0`
e2 := math/ilogb(8.0)        // 3   since `8.0 = 1.0 * 2^3`
e3 := math/ilogb(0.75)       // -1  since `0.75 = 1.5 * 2^-1`
```

(b) Vector input

```mech:ex2
x := [0.5, 1.0, 2.0, 3.0, 4.0]
e := math/ilogb(x)           // [-1, 0, 1, 1, 2]
```

(c) Matrix input

```mech:ex3
m := [0.25, 0.75; 1.0, 6.0]
e := math/ilogb(m)           // [-2, -1; 0, 2]
```

6. Details
-------------------------------------------------------------------------------

- **Element-wise semantics.** Arrays are processed per element; the output shape matches the input shape.
- **Types.** Implemented for `f32` (`ilogbf`) and `f64` (`ilogb`). Output elements are 32-bit integers.
- **Special values (per libm/C99):**
  - `math/ilogb(0)` returns an implementation-defined sentinel (commonly `FP_ILOGB0`), which is a large negative integer.
  - `math/ilogb(±∞)` returns a large positive sentinel (`FP_ILOGBINF`).
  - `math/ilogb(NaN)` returns an implementation-defined value (commonly `FP_ILOGBNAN`).
  - Subnormal inputs return the exponent of their normalized representation.
- **Relationship to frexp** If `x = m * 2^e` with `m ∈ [0.5, 1)`, then `ilogb(x) = floor(log2(|x|))` for normal numbers, and `e - 1` from `frexp` semantics.

**Errors.** Wrong arity (expects exactly one argument) or unsupported dtype.