const_soft_float/soft_f32/
sqrt.rs1use crate::soft_f32::SoftF32;
8use core::cmp::Ordering;
9
10pub(crate) const fn sqrtf(x: SoftF32) -> SoftF32 {
11 const TINY: SoftF32 = SoftF32(1.0e-30);
12
13 let mut z: SoftF32;
14 let sign: i32 = 0x80000000_u32 as i32;
15 let mut ix: i32;
16 let mut s: i32;
17 let mut q: i32;
18 let mut m: i32;
19 let mut t: i32;
20 let mut i: i32;
21 let mut r: u32;
22
23 ix = x.to_bits() as i32;
24
25 if (ix as u32 & 0x7f800000) == 0x7f800000 {
27 return x.mul(x).add(x); }
29
30 if ix <= 0 {
32 if (ix & !sign) == 0 {
33 return x; }
35 if ix < 0 {
36 return (x.sub(x)).div(x.sub(x)); }
38 }
39
40 m = ix >> 23;
42 if m == 0 {
43 i = 0;
45 while ix & 0x00800000 == 0 {
46 ix <<= 1;
47 i = i + 1;
48 }
49 m -= i - 1;
50 }
51 m -= 127; ix = (ix & 0x007fffff) | 0x00800000;
53 if m & 1 == 1 {
54 ix += ix;
56 }
57 m >>= 1; ix += ix;
61 q = 0;
62 s = 0;
63 r = 0x01000000; while r != 0 {
66 t = s + r as i32;
67 if t <= ix {
68 s = t + r as i32;
69 ix -= t;
70 q += r as i32;
71 }
72 ix += ix;
73 r >>= 1;
74 }
75
76 if ix != 0 {
78 z = SoftF32(1.0).sub(TINY); if ge(z, 1.0) {
80 z = SoftF32(1.0).add(TINY);
81 if gt(z, 1.0) {
82 q += 2;
83 } else {
84 q += q & 1;
85 }
86 }
87 }
88
89 ix = (q >> 1) + 0x3f000000;
90 ix += m << 23;
91 SoftF32::from_bits(ix as u32)
92}
93
94const fn gt(l: SoftF32, r: f32) -> bool {
95 if let Some(ord) = l.cmp(SoftF32(r)) {
96 match ord {
97 Ordering::Greater => true,
98 _ => false,
99 }
100 } else {
101 panic!("Failed to compare values");
102 }
103}
104
105const fn ge(l: SoftF32, r: f32) -> bool {
106 if let Some(ord) = l.cmp(SoftF32(r)) {
107 match ord {
108 Ordering::Less => false,
109 _ => true,
110 }
111 } else {
112 panic!("Failed to compare values");
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use super::*;
119 use core::f32::*;
120
121 #[test]
122 fn sanity_check() {
123 assert_eq!(sqrtf(SoftF32(100.0)).0, 10.0);
124 assert_eq!(sqrtf(SoftF32(4.0)).0, 2.0);
125 }
126
127 #[test]
129 fn spec_tests() {
130 assert!(sqrtf(SoftF32(-1.0)).0.is_nan());
132 assert!(sqrtf(SoftF32(NAN)).0.is_nan());
133 for f in [0.0, -0.0, INFINITY].iter().copied() {
134 assert_eq!(sqrtf(SoftF32(f)).0, f);
135 }
136 }
137}