From 6cc9a26a2d61acc0b1d707104f8c2a8b7c990012 Mon Sep 17 00:00:00 2001 From: Matthijs Hofstra Date: Wed, 29 May 2013 16:21:29 +0200 Subject: [PATCH 1/2] Replaced calls to external fmin/fmax by a Rust implementation. --- src/libstd/num/f32.rs | 18 ++++++++++++++++-- src/libstd/num/f64.rs | 17 +++++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 94cff78375af0..0d166c8887cd7 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -86,8 +86,6 @@ delegate!( fn erfc(n: c_float) -> c_float = c_float_utils::erfc, fn exp_m1(n: c_float) -> c_float = c_float_utils::exp_m1, fn abs_sub(a: c_float, b: c_float) -> c_float = c_float_utils::abs_sub, - fn fmax(a: c_float, b: c_float) -> c_float = c_float_utils::fmax, - fn fmin(a: c_float, b: c_float) -> c_float = c_float_utils::fmin, fn next_after(x: c_float, y: c_float) -> c_float = c_float_utils::next_after, fn frexp(n: c_float, value: &mut c_int) -> c_float = c_float_utils::frexp, fn hypot(x: c_float, y: c_float) -> c_float = c_float_utils::hypot, @@ -147,6 +145,22 @@ pub fn ge(x: f32, y: f32) -> bool { return x >= y; } #[inline(always)] pub fn gt(x: f32, y: f32) -> bool { return x > y; } +#[inline(always)] +pub fn fmax(x: f32, y: f32) -> f32 { + if x.is_NaN() { y } + else if y.is_NaN() { x } + else if x > y { x } + else { y } +} + +#[inline(always)] +pub fn fmin(x: f32, y: f32) -> f32 { + if x.is_NaN() { y } + else if y.is_NaN() { x } + else if x < y { x } + else { y } +} + // FIXME (#1999): replace the predicates below with llvm intrinsics or // calls to the libmath macros in the rust runtime for performance. diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index b7754ed07ad72..910e2e1e692bd 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -87,8 +87,6 @@ delegate!( fn erfc(n: c_double) -> c_double = c_double_utils::erfc, fn exp_m1(n: c_double) -> c_double = c_double_utils::exp_m1, fn abs_sub(a: c_double, b: c_double) -> c_double = c_double_utils::abs_sub, - fn fmax(a: c_double, b: c_double) -> c_double = c_double_utils::fmax, - fn fmin(a: c_double, b: c_double) -> c_double = c_double_utils::fmin, fn next_after(x: c_double, y: c_double) -> c_double = c_double_utils::next_after, fn frexp(n: c_double, value: &mut c_int) -> c_double = c_double_utils::frexp, fn hypot(x: c_double, y: c_double) -> c_double = c_double_utils::hypot, @@ -172,6 +170,21 @@ pub fn ge(x: f64, y: f64) -> bool { return x >= y; } #[inline(always)] pub fn gt(x: f64, y: f64) -> bool { return x > y; } +#[inline(always)] +pub fn fmax(x: f64, y: f64) -> f64 { + if x.is_NaN() { y } + else if y.is_NaN() { x } + else if x > y { x } + else { y } +} + +#[inline(always)] +pub fn fmin(x: f64, y: f64) -> f64 { + if x.is_NaN() { y } + else if y.is_NaN() { x } + else if x < y { x } + else { y } +} // FIXME (#1999): add is_normal, is_subnormal, and fpclassify From 3141acf674fd34f66141c4659a4a239779bb2802 Mon Sep 17 00:00:00 2001 From: Matthijs Hofstra Date: Wed, 29 May 2013 20:21:04 +0200 Subject: [PATCH 2/2] Changed to a more efficient implementation. --- src/libstd/num/f32.rs | 10 ++-------- src/libstd/num/f64.rs | 10 ++-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 0d166c8887cd7..b578084268aff 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -147,18 +147,12 @@ pub fn gt(x: f32, y: f32) -> bool { return x > y; } #[inline(always)] pub fn fmax(x: f32, y: f32) -> f32 { - if x.is_NaN() { y } - else if y.is_NaN() { x } - else if x > y { x } - else { y } + if x >= y || y.is_NaN() { x } else { y } } #[inline(always)] pub fn fmin(x: f32, y: f32) -> f32 { - if x.is_NaN() { y } - else if y.is_NaN() { x } - else if x < y { x } - else { y } + if x <= y || y.is_NaN() { x } else { y } } diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 910e2e1e692bd..bca730c574817 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -172,18 +172,12 @@ pub fn gt(x: f64, y: f64) -> bool { return x > y; } #[inline(always)] pub fn fmax(x: f64, y: f64) -> f64 { - if x.is_NaN() { y } - else if y.is_NaN() { x } - else if x > y { x } - else { y } + if x >= y || y.is_NaN() { x } else { y } } #[inline(always)] pub fn fmin(x: f64, y: f64) -> f64 { - if x.is_NaN() { y } - else if y.is_NaN() { x } - else if x < y { x } - else { y } + if x <= y || y.is_NaN() { x } else { y } } // FIXME (#1999): add is_normal, is_subnormal, and fpclassify