1 use core::{f32, u32}; 2 3 #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] fmodf(x: f32, y: f32) -> f324pub 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