pub struct Wide(/* private fields */);Expand description
A product of two Fixed values, kept at full width: Q95.32 in an i128.
§Why this exists
Fixed::saturating_mul narrows its i128 product back to an i64,
which is right for arithmetic that stays in the world and wrong for
geometry that squares things twice. Ray-versus-sphere forms b² − 4ac
where a and c are themselves squared lengths; at ordinary game scales
a·c overflows a Fixed long before the ray does anything unusual, and
the result saturates — deterministically, and to the wrong number.
So the narrowing is deferred. A product of two full-range Fixed values
needs 126 bits and an i128 holds 127, which means a single wide_mul
can never overflow, for any inputs at all. Sums of a few of them cannot
either at any scale a world reaches.
§Contract
- 32 fractional bits, being the sum of its operands’ sixteen. That is
not an implementation detail: it is why
Wide::sqrtneeds no shift. - Ordering is exact, so comparing two products — which is most of what geometry does with them — never rounds at all.
- Narrowing is explicit, and says whether it lost anything.
Implementations§
Source§impl Wide
impl Wide
Sourcepub const fn to_bits(self) -> i128
pub const fn to_bits(self) -> i128
The raw Q95.32 pattern.
There is no from_bits counterpart, deliberately. A Wide is an
intermediate rather than state: it is produced by a multiply and
consumed by a root, a comparison or a narrowing, and nothing
serialises one. An unused constructor is a promise to keep working
that nobody asked for.
Sourcepub fn sqrt(self) -> Fixed
pub fn sqrt(self) -> Fixed
The square root, as a Fixed.
No shift, and that is the point of 32 fractional bits. A Wide
holding the real value v has raw pattern v · 2³², whose integer
square root is √v · 2¹⁶ — exactly a Fixed’s raw pattern. Squaring
and then rooting therefore loses nothing to scaling, where the
narrow path had to shift left by sixteen first and could overflow
doing it.
Floor-exact, by u128::isqrt’s own contract.
§Panics
If negative. See Wide::checked_sqrt.
Sourcepub fn checked_sqrt(self) -> Option<Fixed>
pub fn checked_sqrt(self) -> Option<Fixed>
The square root, or None if negative — which a discriminant is,
routinely, and which is a miss rather than a mistake.
Sourcepub const fn checked_narrow(self) -> Option<Fixed>
pub const fn checked_narrow(self) -> Option<Fixed>
Back to a Fixed, or None if it will not fit.