Skip to main content

renew_fixed/
lib.rs

1//! Fixed-point arithmetic, for simulation code whose output has to reproduce
2//! bit-for-bit on every target.
3//!
4//! # Why this crate exists
5//!
6//! Rust guarantees IEEE 754 semantics for `f32` and `f64` *operators*, and
7//! that guarantee stops at the operators: `sin`, `cos` and their siblings are
8//! the platform's maths library, and are permitted to differ between targets.
9//! A simulation that calls them has no cross-target claim to make.
10//!
11//! Integer arithmetic is bit-identical everywhere, with nothing to police.
12//! That is the whole argument.
13//!
14//! # Contract
15//!
16//! - **Q47.16 in an `i64`.** 16 fractional bits: a resolution of 2⁻¹⁶, and a
17//!   range of ±2⁴⁷. See [`Fixed`] for why those numbers and not others.
18//! - **No `f32` or `f64` in any signature this crate exposes.** Converting to
19//!   a float is a presentation concern, and the conversion is written at the
20//!   boundary that needs it rather than offered here. It cannot be centralised
21//!   in the maths crate: that crate is core and this one is optional, so the
22//!   core-closure rule refuses the edge outright. Nor is centralising it worth
23//!   much — each boundary carries its own precision-loss exemption with its own
24//!   reason, and one shared helper would flatten those into a single reason
25//!   that fits none of them. What stops a simulation from converting is not
26//!   this contract but the float-arithmetic denial it already builds under.
27//! - **Every operation is deterministic and target-independent.** No operation
28//!   here consults a clock, an allocator, an environment variable, or anything
29//!   whose value could differ between two machines running the same build.
30//! - **Overflow saturates, in every build profile, and is counted.** Never
31//!   wraps, never differs between debug and release. See [`Fixed::saturations`].
32
33// This crate is arithmetic; it does not print. And it is the crate simulation
34// arithmetic is written in, so a float operator here would defeat its only
35// purpose — denied rather than left to review, and there is no `allow` below.
36#![deny(clippy::print_stdout, clippy::print_stderr, clippy::float_arithmetic)]
37
38mod angle;
39mod saturation;
40mod scalar;
41mod vector;
42mod wide;
43
44pub use angle::Angle;
45pub use saturation::{Saturations, saturations};
46pub use scalar::Fixed;
47pub use vector::{Vec2, Vec3};
48pub use wide::Wide;