1//! Inverse square root approximation function for a single-precision float.
2//!
3//! Method described at: <https://bits.stephan-brumme.com/invSquareRoot.html>
4
5use super::F32;
6
7impl F32 {
8 /// Approximate inverse square root with an average deviation of ~5%.
9 pub fn invsqrt(self) -> Self {
10 Self::from_bits(0x5f37_5a86 - (self.to_bits() >> 1))
11 }
12}
13
14#[cfg(test)]
15mod tests {
16 use super::F32;
17 use crate::float::sqrt::tests::TEST_VECTORS;
18
19 /// Deviation from the actual value (5%)
20 const MAX_ERROR: f32 = 0.05;
21
22 #[test]
23 fn sanity_check() {
24 for (x, expected) in TEST_VECTORS {
25 // The tests vectors are for sqrt(x), so invert the expected value
26 let expected = 1.0 / expected;
27
28 let invsqrt_x = F32(*x).invsqrt().0;
29 let allowed_delta = x * MAX_ERROR;
30 let actual_delta = invsqrt_x - expected;
31
32 assert!(
33 actual_delta <= allowed_delta,
34 "delta {} too large: {} vs {}",
35 actual_delta,
36 invsqrt_x,
37 expected
38 );
39 }
40 }
41}
42