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