• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use core::{f32, u32};
2 
3 #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
fmodf(x: f32, y: f32) -> f324 pub 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     /* normalize x and y */
25     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     /* x mod y */
52     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     /* scale result up */
79     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 }
89