Skip to content

Commit a749e17

Browse files
committed
Implement fmod and tweak fmodf
1 parent 56e1b0d commit a749e17

File tree

4 files changed

+91
-31
lines changed

4 files changed

+91
-31
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
use core::u64;
2+
3+
#[inline]
4+
pub fn fmod(x: f64, y: f64) -> f64 {
5+
let mut uxi = x.to_bits();
6+
let mut uyi = y.to_bits();
7+
let mut ex = (uxi >> 52 & 0x7ff) as i64;
8+
let mut ey = (uyi >> 52 & 0x7ff) as i64;
9+
let sx = uxi >> 63;
10+
let mut i;
11+
12+
if uyi << 1 == 0 || y.is_nan() || ex == 0x7ff {
13+
return (x * y) / (x * y);
14+
}
15+
if uxi << 1 <= uyi << 1 {
16+
if uxi << 1 == uyi << 1 {
17+
return 0.0 * x;
18+
}
19+
return x;
20+
}
21+
22+
/* normalize x and y */
23+
if ex == 0 {
24+
i = uxi << 12;
25+
while i >> 63 == 0 {
26+
ex -= 1;
27+
i <<= 1;
28+
}
29+
uxi <<= -ex + 1;
30+
} else {
31+
uxi &= u64::MAX >> 12;
32+
uxi |= 1 << 52;
33+
}
34+
if ey == 0 {
35+
i = uyi << 12;
36+
while i >> 63 == 0 {
37+
ey -= 1;
38+
i <<= 1;
39+
}
40+
uyi <<= -ey + 1;
41+
} else {
42+
uyi &= u64::MAX >> 12;
43+
uyi |= 1 << 52;
44+
}
45+
46+
/* x mod y */
47+
while ex > ey {
48+
i = uxi - uyi;
49+
if i >> 63 == 0 {
50+
if i == 0 {
51+
return 0.0 * x;
52+
}
53+
uxi = i;
54+
}
55+
uxi <<= 1;
56+
ex -= 1;
57+
}
58+
i = uxi - uyi;
59+
if i >> 63 == 0 {
60+
if i == 0 {
61+
return 0.0 * x;
62+
}
63+
uxi = i;
64+
}
65+
while uxi >> 52 == 0 {
66+
uxi <<= 1;
67+
ex -= 1;
68+
}
69+
70+
/* scale result */
71+
if ex > 0 {
72+
uxi -= 1 << 52;
73+
uxi |= (ex as u64) << 52;
74+
} else {
75+
uxi >>= -ex + 1;
76+
}
77+
uxi |= (sx as u64) << 63;
78+
79+
f64::from_bits(uxi)
80+
}

library/compiler-builtins/libm/src/math/fmodf.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use core::u32;
22

3-
use super::isnanf;
4-
53
#[inline]
64
pub fn fmodf(x: f32, y: f32) -> f32 {
75
let mut uxi = x.to_bits();
@@ -11,7 +9,7 @@ pub fn fmodf(x: f32, y: f32) -> f32 {
119
let sx = uxi & 0x80000000;
1210
let mut i;
1311

14-
if uyi << 1 == 0 || isnanf(y) || ex == 0xff {
12+
if uyi << 1 == 0 || y.is_nan() || ex == 0xff {
1513
return (x * y) / (x * y);
1614
}
1715

library/compiler-builtins/libm/src/math/mod.rs

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,49 +7,31 @@ macro_rules! force_eval {
77
}
88

99
mod ceilf;
10+
mod expf;
1011
mod fabs;
1112
mod fabsf;
13+
mod floor;
1214
mod floorf;
15+
mod fmod;
1316
mod fmodf;
17+
mod hypot;
18+
mod hypotf;
19+
mod logf;
1420
mod powf;
1521
mod round;
1622
mod roundf;
1723
mod scalbn;
1824
mod scalbnf;
1925
mod sqrt;
2026
mod sqrtf;
21-
mod logf;
22-
mod expf;
23-
mod floor;
2427
mod trunc;
2528
mod truncf;
26-
mod hypot;
27-
mod hypotf;
2829

2930
//mod service;
3031

3132
pub use self::{
32-
ceilf::ceilf,
33-
fabs::fabs,
34-
fabsf::fabsf,
35-
floorf::floorf,
36-
fmodf::fmodf,
37-
powf::powf,
38-
round::round,
39-
roundf::roundf,
40-
scalbn::scalbn,
41-
scalbnf::scalbnf,
42-
sqrt::sqrt,
43-
sqrtf::sqrtf,
44-
logf::logf,
45-
expf::expf,
46-
floor::floor,
47-
trunc::trunc,
33+
ceilf::ceilf, expf::expf, fabs::fabs, fabsf::fabsf, floor::floor, floorf::floorf, fmod::fmod,
34+
fmodf::fmodf, hypot::hypot, hypotf::hypotf, logf::logf, powf::powf, round::round,
35+
roundf::roundf, scalbn::scalbn, scalbnf::scalbnf, sqrt::sqrt, sqrtf::sqrtf, trunc::trunc,
4836
truncf::truncf,
49-
hypot::hypot,
50-
hypotf::hypotf,
5137
};
52-
53-
fn isnanf(x: f32) -> bool {
54-
x.to_bits() & 0x7fffffff > 0x7f800000
55-
}

library/compiler-builtins/libm/test-generator/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ f64_f64! {
724724
f64f64_f64! {
725725
// atan2,
726726
// fdim,
727-
// fmod,
727+
fmod,
728728
hypot,
729729
// pow,
730730
}

0 commit comments

Comments
 (0)