1pub mod tables {
2 include!(concat!(env!("OUT_DIR"), "/tables.rs"));
3}
4
5pub mod u8 {
6 pub mod f32 {
7 pub fn sqrt(x: u8) -> f32 {
8 crate::tables::SQRT_F32[x as usize]
9 }
10 pub fn inv_sqrt(x: u8) -> f32 {
11 crate::tables::INV_SQRT_F32[x as usize]
12 }
13 }
14 pub mod f64 {
15 pub fn sqrt(x: u8) -> f64 {
16 crate::tables::SQRT_F64[x as usize]
17 }
18 pub fn inv_sqrt(x: u8) -> f64 {
19 crate::tables::INV_SQRT_F64[x as usize]
20 }
21 }
22}
23
24macro_rules! generate_inner {
25 ($in:ident, $out:ident) => {
26 pub mod $out {
27 pub fn sqrt(x: $in) -> $out {
28 if x < 256 {
29 crate::u8::$out::sqrt(x as u8)
30 } else {
31 (x as $out).sqrt()
32 }
33 }
34 pub fn inv_sqrt(x: $in) -> $out {
35 if x < 256 {
36 crate::u8::$out::inv_sqrt(x as u8)
37 } else {
38 (x as $out).sqrt().recip()
39 }
40 }
41 }
42 };
43}
44macro_rules! generate {
45 ($in:ident) => {
46 pub mod $in {
47 generate_inner!($in, f32);
48 generate_inner!($in, f64);
49 }
50 };
51}
52generate!(u16);
53generate!(u32);
54generate!(u64);
55generate!(u128);
56
57#[cfg(test)]
58mod test {
59 macro_rules! test {
60 ($in:ident, $count:expr) => {
61 #[test]
62 fn $in() {
63 for x in 0..$count {
64 assert_eq!((x as f32).sqrt(), crate::$in::f32::sqrt(x as $in));
65 assert_eq!((x as f32).sqrt().recip(), crate::$in::f32::inv_sqrt(x as $in));
66 assert_eq!((x as f64).sqrt(), crate::$in::f64::sqrt(x as $in));
67 assert_eq!((x as f64).sqrt().recip(), crate::$in::f64::inv_sqrt(x as $in));
68 }
69 }
70 };
71 }
72 test!(u8, 255);
73 test!(u16, 1024);
74 test!(u32, 1024);
75 test!(u64, 1024);
76 test!(u128, 1024);
77
78 #[test]
79 fn specific_values() {
80 assert_eq!(crate::u8::f32::sqrt(16), 4.);
81 assert_eq!(crate::u8::f32::inv_sqrt(16), 0.25);
82 }
83}