MathUtils 1.0.1

A high-fidelity Rust mirror of the JavaScript (ECMAScript) Math built-in object.
Documentation
# MathUtils

A high-performance, zero-dependency Rust crate that mirrors JavaScript's built-in `Math` object with exact ECMAScript 2024 semantics.

[![Crates.io](https://img.shields.io/badge/crates.io-MathUtils-orange.svg)](https://crates.io)
[![Documentation](https://img.shields.io/badge/docs-API_Reference-blue.svg)](#-documentation)
[![License](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-green.svg)](#-license)

---

## ✨ Features

- **Exact ECMAScript Semantics**: Full fidelity with JavaScript `Math`, including subtle IEEE 754 edge cases:
  - `Math::round(-0.5) == -0.0` (tie-breaking towards $+\infty$)
  - `Math::sign(-0.0) == -0.0` and `Math::sign(+0.0) == +0.0`
  - `Math::pow(NaN, 0.0) == 1.0` and `Math::pow(1.0, Infinity) == NaN`
  - `Math::hypot` with $\pm\infty$ overriding `NaN`
- **Complete Constant Set**: `E`, `LN10`, `LN2`, `LOG10E`, `LOG2E`, `PI`, `SQRT1_2`, `SQRT2` (with snake_case aliases).
- **All JavaScript Methods**: `abs`, `acos`, `acosh`, `asin`, `asinh`, `atan`, `atan2`, `atanh`, `cbrt`, `ceil`, `clz32`, `cos`, `cosh`, `exp`, `expm1`, `floor`, `fround`, `f16round` (ES2024), `hypot`, `imul`, `log`, `log1p`, `log10`, `log2`, `max`, `min`, `pow`, `random`, `round`, `sign`, `sin`, `sinh`, `sqrt`, `sumPrecise` (ES2024), `tan`, `tanh`, `trunc`.
- **Zero External Dependencies**: Pure Rust standard library.
- **Fast, Thread-Safe PRNG**: High-performance Xoshiro256++ generator for `Math::random()` with thread-local state and seedable testing support.
- **Variadic Macros**: `math_max!`, `math_min!`, `math_hypot!` providing variadic JavaScript-style calling ergonomics.
- **Clean `Math` Namespace**: Access all constants and methods directly through the `Math` struct (`Math::cos(...)`, `Math::PI`, `Math::round(...)`), mirroring JavaScript's syntax.

---

## 📦 Installation

Add to your `Cargo.toml`:

```toml
[dependencies]
MathUtils = "1.0.1"
```

Or run via `cargo`:

```bash
cargo add MathUtils
```

---

## 🚀 Quick Start

```rust
use MathUtils::{Math, math_max, math_min, math_hypot};

fn main() {
    // 1. Exact JavaScript Rounding
    assert_eq!(Math::round(-0.5), -0.0);
    assert_eq!(Math::round(1.5), 2.0);
    assert_eq!(Math::round(-1.5), -1.0);

    // 2. Constants & Trigonometry
    println!("Pi: {}", Math::PI);
    println!("Cos(0): {}", Math::cos(0.0));
    println!("Atan2(0, -0): {}", Math::atan2(0.0, -0.0)); // Pi

    // 3. Integer Operations & Type Coercion
    assert_eq!(Math::imul(0xffff_ffffu32, 5), -5);
    assert_eq!(Math::clz32(1000.0), 22);

    // 4. IEEE 754 Float Conversions
    assert_eq!(Math::fround(1.337), 1.3370000123977661);
    assert_eq!(Math::f16round(Math::PI), 3.140625);

    // 5. Compensated Exact Summation (ES2024 Math.sumPrecise)
    let numbers = [1e16, 1.0, -1e16];
    assert_eq!(Math::sumPrecise(&numbers), 1.0);

    // 6. Variadic Macros
    assert_eq!(math_max!(1.0, 99.5, -42.0), 99.5);
    assert_eq!(math_min!(1.0, 99.5, -42.0), -42.0);
    assert_eq!(math_hypot!(3.0, 4.0), 5.0);

    // 7. Pseudo-random Number Generation
    let r = Math::random();
    println!("Random in [0, 1): {}", r);
}
```

---

## 📚 Documentation

You can generate and view the complete HTML API documentation locally by running:

```bash
cargo doc --no-deps --open
```

---

## 📖 API Reference

### Constants

| Constant                           | Value                | Description                                     |
| :--------------------------------- | :------------------- | :---------------------------------------------- |
| `Math::E`                          | `2.718281828459045`  | Euler's constant and base of natural logarithms |
| `Math::LN10` / `Math::LN_10`       | `2.302585092994046`  | Natural logarithm of 10                         |
| `Math::LN2` / `Math::LN_2`         | `0.6931471805599453` | Natural logarithm of 2                          |
| `Math::LOG10E` / `Math::LOG10_E`   | `0.4342944819032518` | Base-10 logarithm of E                          |
| `Math::LOG2E` / `Math::LOG2_E`     | `1.4426950408889634` | Base-2 logarithm of E                           |
| `Math::PI`                         | `3.141592653589793`  | Ratio of circumference to diameter              |
| `Math::SQRT1_2` / `Math::SQRT_1_2` | `0.7071067811865476` | Square root of 1/2                              |
| `Math::SQRT2` / `Math::SQRT_2`     | `1.4142135623730951` | Square root of 2                                |

### Methods

| Function                     | Signature                                         | Description                                                     |
| :--------------------------- | :------------------------------------------------ | :-------------------------------------------------------------- |
| `abs`                        | `(x: f64) -> f64`                                 | Absolute value (preserves `NaN`, converts `-0.0` to `+0.0`)     |
| `acos`                       | `(x: f64) -> f64`                                 | Arccosine in radians                                            |
| `acosh`                      | `(x: f64) -> f64`                                 | Hyperbolic arccosine                                            |
| `asin`                       | `(x: f64) -> f64`                                 | Arcsine in radians                                              |
| `asinh`                      | `(x: f64) -> f64`                                 | Hyperbolic arcsine                                              |
| `atan`                       | `(x: f64) -> f64`                                 | Arctangent in radians                                           |
| `atanh`                      | `(x: f64) -> f64`                                 | Hyperbolic arctangent                                           |
| `atan2`                      | `(y: f64, x: f64) -> f64`                         | 4-quadrant arctangent of $y/x$                                  |
| `cbrt`                       | `(x: f64) -> f64`                                 | Cube root                                                       |
| `ceil`                       | `(x: f64) -> f64`                                 | Smallest integer $\ge x$                                        |
| `clz32`                      | `<T: ToJsUint32>(x: T) -> u32`                    | Number of leading zero bits in 32-bit binary representation     |
| `cos`                        | `(x: f64) -> f64`                                 | Cosine in radians                                               |
| `cosh`                       | `(x: f64) -> f64`                                 | Hyperbolic cosine                                               |
| `exp`                        | `(x: f64) -> f64`                                 | $e^x$                                                           |
| `expm1`                      | `(x: f64) -> f64`                                 | $e^x - 1$                                                       |
| `floor`                      | `(x: f64) -> f64`                                 | Largest integer $\le x$                                         |
| `fround`                     | `(x: f64) -> f64`                                 | Round to nearest IEEE 754 32-bit float                          |
| `f16round`                   | `(x: f64) -> f64`                                 | Round to nearest IEEE 754 16-bit half-precision float (ES2024)  |
| `hypot`                      | `(values: &[f64]) -> f64`                         | Square root of sum of squares ($\pm\infty$ overrides `NaN`)     |
| `hypot2`                     | `(x: f64, y: f64) -> f64`                         | 2-argument hypotenuse                                           |
| `imul`                       | `<A: ToJsInt32, B: ToJsInt32>(a: A, b: B) -> i32` | 32-bit integer multiplication                                   |
| `log`                        | `(x: f64) -> f64`                                 | Natural logarithm $\ln(x)$                                      |
| `log1p` / `log_1p`           | `(x: f64) -> f64`                                 | $\ln(1 + x)$                                                    |
| `log10` / `log_10`           | `(x: f64) -> f64`                                 | Base-10 logarithm                                               |
| `log2` / `log_2`             | `(x: f64) -> f64`                                 | Base-2 logarithm                                                |
| `max`                        | `(values: &[f64]) -> f64`                         | Maximum element (empty returns $-\infty$, preserves zero signs) |
| `max2`                       | `(a: f64, b: f64) -> f64`                         | 2-argument maximum                                              |
| `min`                        | `(values: &[f64]) -> f64`                         | Minimum element (empty returns $+\infty$, preserves zero signs) |
| `min2`                       | `(a: f64, b: f64) -> f64`                         | 2-argument minimum                                              |
| `pow`                        | `(base: f64, exponent: f64) -> f64`               | $base^{exponent}$ with ECMA-262 edge-case handling              |
| `random`                     | `() -> f64`                                       | Pseudo-random float in $[0.0, 1.0)$                             |
| `seed_random`                | `(seed: u64)`                                     | Reseed thread-local PRNG for deterministic testing              |
| `round`                      | `(x: f64) -> f64`                                 | ECMAScript half-up rounding (`round(-0.5) == -0.0`)             |
| `sign`                       | `(x: f64) -> f64`                                 | Sign of number (`+1.0`, `-1.0`, `+0.0`, `-0.0`, `NaN`)          |
| `sin`                        | `(x: f64) -> f64`                                 | Sine in radians                                                 |
| `sinh`                       | `(x: f64) -> f64`                                 | Hyperbolic sine                                                 |
| `sqrt`                       | `(x: f64) -> f64`                                 | Square root                                                     |
| `sumPrecise` / `sum_precise` | `<I>(items: I) -> f64`                            | Shewchuk exact compensated summation (ES2024)                   |
| `tan`                        | `(x: f64) -> f64`                                 | Tangent in radians                                              |
| `tanh`                       | `(x: f64) -> f64`                                 | Hyperbolic tangent                                              |
| `trunc`                      | `(x: f64) -> f64`                                 | Truncate fractional digits                                      |

---

## 🔍 JavaScript vs. Standard Rust Floating-Point Differences Handled

| Operation                 | Rust `std` / C `libm`               | JS `Math` / `MathUtils`              | Notes                                          |
| :------------------------ | :---------------------------------- | :----------------------------------- | :--------------------------------------------- |
| `round(-0.5)`             | `-1.0` (round half away from 0)     | `-0.0` (round half toward $+\infty$) | Preserves `-0.0` sign                          |
| `round(-1.5)`             | `-2.0`                              | `-1.0`                               | Ties break towards $+\infty$                   |
| `sign(-0.0)`              | `-1.0`                              | `-0.0`                               | Preserves zero signs                           |
| `pow(NaN, 0.0)`           | `1.0` or `NaN` (platform dependent) | `1.0`                                | Explicitly mandated by ECMA-262                |
| `pow(1.0, Infinity)`      | `1.0` (IEEE 754-2008)               | `NaN`                                | Explicitly mandated by ECMA-262                |
| `pow(-1.0, Infinity)`     | `1.0` (IEEE 754-2008)               | `NaN`                                | Explicitly mandated by ECMA-262                |
| `hypot(&[Infinity, NaN])` | `NaN` in standard slices            | `Infinity`                           | ECMA-262 specifies $\pm\infty$ overrides `NaN` |
| `max(&[])`                | N/A (panics or returns `None`)      | `-Infinity`                          | Matches JS `Math.max()`                        |
| `min(&[])`                | N/A (panics or returns `None`)      | `+Infinity`                          | Matches JS `Math.min()`                        |

---

## 📜 License

Licensed under either of:

- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT]LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.