From 39ac651a9f7039badcf3326cfac89b6b3f712be1 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 13 Jul 2018 00:40:05 +0000 Subject: [PATCH 1/3] Implement `round` --- src/lib.rs | 6 ++++++ src/math/mod.rs | 2 ++ src/math/round.rs | 35 +++++++++++++++++++++++++++++++++++ test-generator/src/main.rs | 2 +- 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/math/round.rs diff --git a/src/lib.rs b/src/lib.rs index fc9628d..f54366b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,12 @@ #![deny(warnings)] #![no_std] +macro_rules! force_eval { + ($e:expr) => { + unsafe { ::core::ptr::read_volatile(&$e); } + } +} + mod math; #[cfg(todo)] diff --git a/src/math/mod.rs b/src/math/mod.rs index 09d8194..c150a62 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -2,6 +2,7 @@ mod fabs; mod fabsf; mod fmodf; mod powf; +mod round; mod scalbnf; mod sqrtf; @@ -9,6 +10,7 @@ pub use self::fabs::fabs; pub use self::fabsf::fabsf; pub use self::fmodf::fmodf; pub use self::powf::powf; +pub use self::round::round; pub use self::scalbnf::scalbnf; pub use self::sqrtf::sqrtf; diff --git a/src/math/round.rs b/src/math/round.rs new file mode 100644 index 0000000..2a9f67c --- /dev/null +++ b/src/math/round.rs @@ -0,0 +1,35 @@ +use core::f64; + +const TOINT: f64 = 1.0 / f64::EPSILON; + +pub fn round(mut x: f64) -> f64 { + let (f, i) = (x, x.to_bits()); + let e: u64 = i >> 52 & 0x7ff; + let mut y: f64; + + if e >= 0x3ff + 52 { + return x; + } + if i >> 63 != 0 { + x = -x; + } + if e < 0x3ff - 1 { + // raise inexact if x!=0 + force_eval!(x + TOINT); + return 0.0 * f; + } + y = x + TOINT - TOINT - x; + if y > 0.5 { + y = y + x - 1.0; + } else if y <= -0.5 { + y = y + x + 1.0; + } else { + y = y + x; + } + + if i >> 63 != 0 { + -y + } else { + y + } +} diff --git a/test-generator/src/main.rs b/test-generator/src/main.rs index a13aa4e..5ff78ff 100644 --- a/test-generator/src/main.rs +++ b/test-generator/src/main.rs @@ -618,7 +618,7 @@ f64_f64! { // log10, // log1p, // log2, - // round, + round, // sin, // sinh, // sqrt, From ac9e81b9c59ff4a517a1c3df55ff9a7f39d51c0f Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 13 Jul 2018 01:25:46 +0000 Subject: [PATCH 2/3] Enable f64::round --- src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f54366b..06ef459 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -383,7 +383,6 @@ pub trait F64Ext { #[cfg(todo)] fn ceil(self) -> Self; - #[cfg(todo)] fn round(self) -> Self; #[cfg(todo)] @@ -504,7 +503,6 @@ impl F64Ext for f64 { ceil(self) } - #[cfg(todo)] #[inline] fn round(self) -> Self { round(self) From dd2bbcb89033bf1aff43f7edb35edc464535ae87 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 13 Jul 2018 01:38:04 +0000 Subject: [PATCH 3/3] Move the `force_eval!` macro into the math module This fixes the cross-inclusion into the compiler builtins --- src/lib.rs | 6 ------ src/math/mod.rs | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 06ef459..0d13590 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,12 +12,6 @@ #![deny(warnings)] #![no_std] -macro_rules! force_eval { - ($e:expr) => { - unsafe { ::core::ptr::read_volatile(&$e); } - } -} - mod math; #[cfg(todo)] diff --git a/src/math/mod.rs b/src/math/mod.rs index c150a62..41359bf 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -1,3 +1,9 @@ +macro_rules! force_eval { + ($e:expr) => { + unsafe { ::core::ptr::read_volatile(&$e); } + } +} + mod fabs; mod fabsf; mod fmodf;