79: implement ceil r=japaric a=lucasmarqs

closes rust-lang/libm#53 

Co-authored-by: Lucas Marques <lucas.smarques@outlook.com>
Co-authored-by: Jorge Aparicio <jorge@japaric.io>
This commit is contained in:
bors[bot] 2018-07-14 16:19:53 +00:00
commit d144863cec
4 changed files with 42 additions and 3 deletions

View file

@ -347,7 +347,6 @@ impl F32Ext for f32 {
pub trait F64Ext: private::Sealed {
fn floor(self) -> Self;
#[cfg(todo)]
fn ceil(self) -> Self;
fn round(self) -> Self;
@ -455,7 +454,6 @@ impl F64Ext for f64 {
floor(self)
}
#[cfg(todo)]
#[inline]
fn ceil(self) -> Self {
ceil(self)

View file

@ -0,0 +1,39 @@
use core::f64;
const TOINT: f64 = 1. / f64::EPSILON;
#[inline]
pub fn ceil(x: f64) -> f64 {
let u: u64 = x.to_bits();
let e: i64 = (u >> 52 & 0x7ff) as i64;
let y: f64;
if e >= 0x3ff + 52 || x == 0. {
return x;
}
// y = int(x) - x, where int(x) is an integer neighbor of x
y = if (u >> 63) != 0 {
x - TOINT + TOINT - x
} else {
x + TOINT - TOINT - x
};
// special case because of non-nearest rounding modes
if e <= 0x3ff - 1 {
force_eval!(y);
return if (u >> 63) != 0 { -0. } else { 1. };
}
if y < 0. {
x + y + 1.
} else {
x + y
}
}
#[cfg(test)]
mod tests {
#[test]
fn sanity_check() {
assert_eq!(super::ceil(1.1), 2.0);
assert_eq!(super::ceil(2.9), 3.0);
}
}

View file

@ -6,6 +6,7 @@ macro_rules! force_eval {
};
}
mod ceil;
mod ceilf;
mod cosf;
mod expf;
@ -35,6 +36,7 @@ mod trunc;
mod truncf;
// Use separated imports instead of {}-grouped imports for easier merging.
pub use self::ceil::ceil;
pub use self::ceilf::ceilf;
pub use self::cosf::cosf;
pub use self::expf::expf;

View file

@ -700,7 +700,7 @@ f64_f64! {
// asin,
// atan,
// cbrt,
// ceil,
ceil,
// cos,
// cosh,
// exp,