Skip to content

Commit 65cfc98

Browse files
authored
Merge pull request rust-lang/libm#2 from japaric/fmodf
implement fmodf
2 parents b4a3b4d + fc5fe1f commit 65cfc98

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

libm/src/fmodf.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
use core::u32;
2+
3+
use isnanf;
4+
5+
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 || isnanf(y) || 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 - 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 - 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+
}

libm/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
#![no_std]
33

44
mod fabsf;
5+
mod fmodf;
56
mod powf;
67
mod scalbnf;
78
mod sqrtf;
89

910
pub use fabsf::fabsf;
11+
pub use fmodf::fmodf;
1012
pub use powf::powf;
1113
pub use scalbnf::scalbnf;
1214
pub use sqrtf::sqrtf;
@@ -16,3 +18,7 @@ pub use sqrtf::sqrtf;
1618
pub fn _eqf(a: u32, b: u32) -> bool {
1719
(a as i32).wrapping_sub(b as i32).abs() <= 1
1820
}
21+
22+
fn isnanf(x: f32) -> bool {
23+
x.to_bits() & 0x7fffffff > 0x7f800000
24+
}

libm/test-generator/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ f32_f32! {
225225

226226
// With signature `fn(f32, f32) -> f32`
227227
f32f32_f32! {
228+
fmodf,
228229
powf,
229230
}
230231

0 commit comments

Comments
 (0)