1const HYPOT_SPLIT: f64 = asdouble(0x41A0000002000000); const HYPOTF_SCALE_UP: f32 = asfloat(0x6C800000); const HYPOTF_SCALE_DN: f32 = asfloat(0x12800000); #[no_mangle]
18pub extern "C" fn hypotf(x: f32, y: f32) -> f32 {
19 let mut ux = asuint(x) & 0x7FFFFFFF;
20 let mut uy = asuint(y) & 0x7FFFFFFF;
21
22 if ux < uy {
23 let ut = ux;
24 ux = uy;
25 uy = ut;
26 }
27
28 let mut x = asfloat(ux);
29 let mut y = asfloat(uy);
30
31 if uy == 0xFF << 23 {
33 return y;
34 }
35 if ux >= 0xFF << 23 || uy == 0 || ux.wrapping_sub(uy) >= 25 << 23 {
36 return x + y;
37 }
38
39 let mut z: f32 = 1.0;
40 if ux >= (0x7F + 60) << 23 {
41 z = HYPOTF_SCALE_UP;
42 x *= HYPOTF_SCALE_DN;
43 y *= HYPOTF_SCALE_DN;
44 } else if uy < (0x7F - 60) << 23 {
45 z = HYPOTF_SCALE_DN;
46 x *= HYPOTF_SCALE_UP;
47 y *= HYPOTF_SCALE_UP;
48 }
49 z * sqrtf(((x as f64) * (x as f64) + (y as f64) * (y as f64)) as f32)
50}
51
52const HYPOT_SCALE_UP: f64 = asdouble(0x6BB0000000000000); const HYPOT_SCALE_DN: f64 = asdouble(0x1430000000000000); #[inline]
62fn hypot_sq(x: f64) -> (f64, f64) {
63 let xc = x * HYPOT_SPLIT;
64 let xh = x - xc + xc;
65 let xl = x - xh;
66 let hi = x * x;
67 let lo = xh * xh - hi + 2.0 * xh * xl + xl * xl;
68 (hi, lo)
69}
70
71#[no_mangle]
72pub extern "C" fn hypot(x: f64, y: f64) -> f64 {
73 let mut ux = asuint64(x) & 0x7FFFFFFFFFFFFFFF;
74 let mut uy = asuint64(y) & 0x7FFFFFFFFFFFFFFF;
75
76 if ux < uy {
78 let ut = ux;
79 ux = uy;
80 uy = ut;
81 }
82
83 let ex = (ux >> 52) as i32;
84 let ey = (uy >> 52) as i32;
85 let x = asdouble(ux);
86 let y = asdouble(uy);
87
88 if ey == 0x7FF {
90 return y;
91 }
92 if ex == 0x7FF || uy == 0 {
93 return x;
94 }
95 if ex - ey > 64 {
97 return x + y;
98 }
99
100 let mut z: f64 = 1.0;
103 let mut x = x;
104 let mut y = y;
105 if ex > 0x3FF + 510 {
106 z = HYPOT_SCALE_UP;
107 x *= HYPOT_SCALE_DN;
108 y *= HYPOT_SCALE_DN;
109 } else if ey < 0x3FF - 450 {
110 z = HYPOT_SCALE_DN;
111 x *= HYPOT_SCALE_UP;
112 y *= HYPOT_SCALE_UP;
113 }
114
115 let (hx, lx) = hypot_sq(x);
116 let (hy, ly) = hypot_sq(y);
117 z * sqrt(ly + lx + hy + hx)
118}