1use core::{f32, u32};
2
3#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
4pub fn fmodf(x: f32, y: f32) -> f32 {
5 let mut uxi = x.to_bits();
6 let mut uyi = y.to_bits();
7 let mut ex = (uxi >> 23 & 0xff) as i32;
8 let mut ey = (uyi >> 23 & 0xff) as i32;
9 let sx = uxi & 0x80000000;
10 let mut i;
11
12 if uyi << 1 == 0 || y.is_nan() || ex == 0xff {
13 return (x * y) / (x * y);
14 }
15
16 if uxi << 1 <= uyi << 1 {
17 if uxi << 1 == uyi << 1 {
18 return 0.0 * x;
19 }
20
21 return x;
22 }
23
24 if ex == 0 {
26 i = uxi << 9;
27 while i >> 31 == 0 {
28 ex -= 1;
29 i <<= 1;
30 }
31
32 uxi <<= -ex + 1;
33 } else {
34 uxi &= u32::MAX >> 9;
35 uxi |= 1 << 23;
36 }
37
38 if ey == 0 {
39 i = uyi << 9;
40 while i >> 31 == 0 {
41 ey -= 1;
42 i <<= 1;
43 }
44
45 uyi <<= -ey + 1;
46 } else {
47 uyi &= u32::MAX >> 9;
48 uyi |= 1 << 23;
49 }
50
51 while ex > ey {
53 i = uxi.wrapping_sub(uyi);
54 if i >> 31 == 0 {
55 if i == 0 {
56 return 0.0 * x;
57 }
58 uxi = i;
59 }
60 uxi <<= 1;
61
62 ex -= 1;
63 }
64
65 i = uxi.wrapping_sub(uyi);
66 if i >> 31 == 0 {
67 if i == 0 {
68 return 0.0 * x;
69 }
70 uxi = i;
71 }
72
73 while uxi >> 23 == 0 {
74 uxi <<= 1;
75 ex -= 1;
76 }
77
78 if ex > 0 {
80 uxi -= 1 << 23;
81 uxi |= (ex as u32) << 23;
82 } else {
83 uxi >>= -ex + 1;
84 }
85 uxi |= sx;
86
87 f32::from_bits(uxi)
88}