Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit b0edbd8

Browse files
committed
Add newlib floorf
1 parent 6cb1d6e commit b0edbd8

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

src/math/floorf.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* sf_floor.c -- float version of s_floor.c.
2+
* Conversion to float by Ian Lance Taylor, Cygnus Support, [email protected].
3+
*/
4+
5+
/*
6+
* ====================================================
7+
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8+
*
9+
* Developed at SunPro, a Sun Microsystems, Inc. business.
10+
* Permission to use, copy, modify, and distribute this
11+
* software is freely granted, provided that this notice
12+
* is preserved.
13+
* ====================================================
14+
*/
15+
16+
const HUGE: f32 = 1.0e30;
17+
18+
/// Return x rounded toward -inf to integral value
19+
#[inline]
20+
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
21+
pub fn floorf(x: f32) -> f32 {
22+
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
23+
// `f32.floor` native instruction, so we can leverage this for both code size
24+
// and speed.
25+
llvm_intrinsically_optimized! {
26+
#[cfg(target_arch = "wasm32")] {
27+
return unsafe { ::core::intrinsics::floorf32(x) }
28+
}
29+
}
30+
31+
use super::fdlibm::{FLT_UWORD_IS_FINITE, FLT_UWORD_IS_ZERO};
32+
33+
let mut i0: u32 = x.to_bits();
34+
let ix: u32 = i0 & 0x7fff_ffff;
35+
let j0: i32 = (ix >> 23) as i32 - 0x7f;
36+
let sign: bool = (i0 >> 31) != 0;
37+
38+
if j0 < 23 {
39+
if j0 < 0 {
40+
/* raise inexact if x != 0 */
41+
if HUGE + x > 0.0 {
42+
/* return 0*sign(x) if |x|<1 */
43+
if !sign {
44+
i0 = 0;
45+
} else if !FLT_UWORD_IS_ZERO(ix) {
46+
i0 = 0xbf80_0000;
47+
}
48+
}
49+
} else {
50+
let i = 0x007f_ffff >> j0;
51+
if i0 & i == 0 {
52+
return x; /* x is integral */
53+
}
54+
if HUGE + x > 0.0 {
55+
/* raise inexact flag */
56+
if sign {
57+
i0 += 0x0080_0000 >> j0;
58+
}
59+
i0 &= !i;
60+
}
61+
}
62+
} else {
63+
if !FLT_UWORD_IS_FINITE(ix) {
64+
return x + x; /* inf or NaN */
65+
} else {
66+
return x; /* x is integral */
67+
}
68+
}
69+
f32::from_bits(i0)
70+
}
71+
72+
#[cfg(test)]
73+
mod tests {
74+
#[test]
75+
fn no_overflow() {
76+
assert_eq!(super::floorf(0.5), 0.0);
77+
}
78+
}

0 commit comments

Comments
 (0)