1use core::f64;
2
3use super::sqrt;
4
5const SPLIT: f64 = 134217728. + 1.; fn sq(x: f64) -> (f64, f64) {
8 let xh: f64;
9 let xl: f64;
10 let xc: f64;
11
12 xc = x * SPLIT;
13 xh = x - xc + xc;
14 xl = x - xh;
15 let hi = x * x;
16 let lo = xh * xh - hi + 2. * xh * xl + xl * xl;
17 (hi, lo)
18}
19
20#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
21pub fn hypot(mut x: f64, mut y: f64) -> f64 {
22 let x1p700 = f64::from_bits(0x6bb0000000000000); let x1p_700 = f64::from_bits(0x1430000000000000); let mut uxi = x.to_bits();
26 let mut uyi = y.to_bits();
27 let uti;
28 let ex: i64;
29 let ey: i64;
30 let mut z: f64;
31
32 uxi &= -1i64 as u64 >> 1;
34 uyi &= -1i64 as u64 >> 1;
35 if uxi < uyi {
36 uti = uxi;
37 uxi = uyi;
38 uyi = uti;
39 }
40
41 ex = (uxi >> 52) as i64;
43 ey = (uyi >> 52) as i64;
44 x = f64::from_bits(uxi);
45 y = f64::from_bits(uyi);
46 if ey == 0x7ff {
48 return y;
49 }
50 if ex == 0x7ff || uyi == 0 {
51 return x;
52 }
53 if ex - ey > 64 {
56 return x + y;
57 }
58
59 z = 1.;
62 if ex > 0x3ff + 510 {
63 z = x1p700;
64 x *= x1p_700;
65 y *= x1p_700;
66 } else if ey < 0x3ff - 450 {
67 z = x1p_700;
68 x *= x1p700;
69 y *= x1p700;
70 }
71 let (hx, lx) = sq(x);
72 let (hy, ly) = sq(y);
73 z * sqrt(ly + lx + hy + hx)
74}