1#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
2pub fn remquof(mut x: f32, mut y: f32) -> (f32, i32) {
3 let ux: u32 = x.to_bits();
4 let mut uy: u32 = y.to_bits();
5 let mut ex = ((ux >> 23) & 0xff) as i32;
6 let mut ey = ((uy >> 23) & 0xff) as i32;
7 let sx = (ux >> 31) != 0;
8 let sy = (uy >> 31) != 0;
9 let mut q: u32;
10 let mut i: u32;
11 let mut uxi: u32 = ux;
12
13 if (uy << 1) == 0 || y.is_nan() || ex == 0xff {
14 return ((x * y) / (x * y), 0);
15 }
16 if (ux << 1) == 0 {
17 return (x, 0);
18 }
19
20 /* normalize x and y */
21 if ex == 0 {
22 i = uxi << 9;
23 while (i >> 31) == 0 {
24 ex -= 1;
25 i <<= 1;
26 }
27 uxi <<= -ex + 1;
28 } else {
29 uxi &= (!0) >> 9;
30 uxi |= 1 << 23;
31 }
32 if ey == 0 {
33 i = uy << 9;
34 while (i >> 31) == 0 {
35 ey -= 1;
36 i <<= 1;
37 }
38 uy <<= -ey + 1;
39 } else {
40 uy &= (!0) >> 9;
41 uy |= 1 << 23;
42 }
43
44 q = 0;
45 if ex + 1 != ey {
46 if ex < ey {
47 return (x, 0);
48 }
49 /* x mod y */
50 while ex > ey {
51 i = uxi.wrapping_sub(uy);
52 if (i >> 31) == 0 {
53 uxi = i;
54 q += 1;
55 }
56 uxi <<= 1;
57 q <<= 1;
58 ex -= 1;
59 }
60 i = uxi.wrapping_sub(uy);
61 if (i >> 31) == 0 {
62 uxi = i;
63 q += 1;
64 }
65 if uxi == 0 {
66 ex = -30;
67 } else {
68 while (uxi >> 23) == 0 {
69 uxi <<= 1;
70 ex -= 1;
71 }
72 }
73 }
74
75 /* scale result and decide between |x| and |x|-|y| */
76 if ex > 0 {
77 uxi -= 1 << 23;
78 uxi |= (ex as u32) << 23;
79 } else {
80 uxi >>= -ex + 1;
81 }
82 x = f32::from_bits(uxi);
83 if sy {
84 y = -y;
85 }
86 if ex == ey || (ex + 1 == ey && (2.0 * x > y || (2.0 * x == y && (q % 2) != 0))) {
87 x -= y;
88 q += 1;
89 }
90 q &= 0x7fffffff;
91 let quo = if sx ^ sy { -(q as i32) } else { q as i32 };
92 if sx {
93 (-x, quo)
94 } else {
95 (x, quo)
96 }
97}
98