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) -> f325pub 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