libm/math/
remquof.rs

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 { (-x, quo) } else { (x, quo) }
93}