# `Ascii.Int32`
[🔗](https://github.com/houllette/ascii_art/blob/main/lib/ascii/int32.ex#L1)

JavaScript's 32-bit integer operators.

JS converts both operands of `|`, `&`, `^`, `<<`, `>>` and `>>>` to 32 bits
and gives a signed 32-bit result (unsigned for `>>>`); `Math.imul`
multiplies modulo 2^32. Elixir integers never overflow, so the pieces' hashes
and PRNGs go through these functions rather than `Bitwise` directly.

Every function accepts any integer, or a float, which is truncated first
as JS's ToInt32 does.

# `int32`

```elixir
@type int32() :: -2_147_483_648..2_147_483_647
```

A signed 32-bit integer.

# `uint32`

```elixir
@type uint32() :: 0..4_294_967_295
```

An unsigned 32-bit integer.

# `band`

```elixir
@spec band(a :: number(), b :: number()) :: int32()
```

`a & b`.

# `bor`

```elixir
@spec bor(a :: number(), b :: number()) :: int32()
```

`a | b`.

# `bxor`

```elixir
@spec bxor(a :: number(), b :: number()) :: int32()
```

`a ^ b`.

# `imul`

```elixir
@spec imul(a :: number(), b :: number()) :: int32()
```

`Math.imul(a, b)`, without building a 64-bit product.

# `mulberry32`

```elixir
@spec mulberry32(state :: int32()) :: {float(), int32()}
```

One draw from mulberry32, the PRNG most pieces seed: given the state, the
next number in [0, 1) and the next state. Start from `to_int32(seed)`.

    a = (a + 0x6d2b79f5) | 0;
    let t = Math.imul(a ^ (a >>> 15), 1 | a);
    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;

# `sar`

```elixir
@spec sar(a :: number(), n :: number()) :: int32()
```

`a >> n`.

# `shl`

```elixir
@spec shl(a :: number(), n :: number()) :: int32()
```

`a << n`.

# `to_int32`

```elixir
@spec to_int32(x :: number()) :: int32()
```

`x | 0`.

# `to_uint32`

```elixir
@spec to_uint32(x :: number()) :: uint32()
```

`x >>> 0`.

# `u32`

```elixir
@spec u32(x :: number()) :: uint32()
```

`x >>> 0` for a value already known to be an integer or a float, without
the sign handling: the fast path for hashes, which stay unsigned.

# `umul`

```elixir
@spec umul(a :: uint32(), b :: uint32()) :: uint32()
```

`Math.imul(a, b) >>> 0` for two unsigned 32-bit integers.

A hash that only ever feeds `^`, `>>>`, `+` and `Math.imul` with its
intermediate values can work in unsigned arithmetic throughout, since all
four agree modulo 2^32 whatever the signs; this skips `imul/2`'s
conversions and is several times faster.

# `ushr`

```elixir
@spec ushr(a :: number(), n :: number()) :: uint32()
```

`a >>> n`.

---

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