add correct floating point min and max methods.
The `std::cmp` functions are not correct for floating point types. `min(NaN, 2.0)` and `min(2.0, NaN)` return different values, because these functions assume a total order. Floating point types need special `min`, `max` and `clamp` functions.
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
//! Operations and constants for 32-bits floats (`f32` type)
|
//! Operations and constants for 32-bits floats (`f32` type)
|
||||||
|
|
||||||
#[allow(missing_doc)];
|
#[allow(missing_doc)];
|
||||||
|
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
@@ -311,6 +312,16 @@ impl Bounded for f32 {
|
|||||||
impl Primitive for f32 {}
|
impl Primitive for f32 {}
|
||||||
|
|
||||||
impl Float for f32 {
|
impl Float for f32 {
|
||||||
|
#[inline]
|
||||||
|
fn max(self, other: f32) -> f32 {
|
||||||
|
unsafe { cmath::c_float::fmax(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn min(self, other: f32) -> f32 {
|
||||||
|
unsafe { cmath::c_float::fmin(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn nan() -> f32 { 0.0 / 0.0 }
|
fn nan() -> f32 { 0.0 / 0.0 }
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ use num::{Zero, One, Bounded, strconv};
|
|||||||
use num;
|
use num;
|
||||||
use intrinsics;
|
use intrinsics;
|
||||||
|
|
||||||
pub use cmp::{min, max};
|
|
||||||
|
|
||||||
macro_rules! delegate(
|
macro_rules! delegate(
|
||||||
(
|
(
|
||||||
$(
|
$(
|
||||||
@@ -313,6 +311,16 @@ impl Bounded for f64 {
|
|||||||
impl Primitive for f64 {}
|
impl Primitive for f64 {}
|
||||||
|
|
||||||
impl Float for f64 {
|
impl Float for f64 {
|
||||||
|
#[inline]
|
||||||
|
fn max(self, other: f64) -> f64 {
|
||||||
|
unsafe { cmath::c_double::fmax(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn min(self, other: f64) -> f64 {
|
||||||
|
unsafe { cmath::c_double::fmin(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn nan() -> f64 { 0.0 / 0.0 }
|
fn nan() -> f64 { 0.0 / 0.0 }
|
||||||
|
|
||||||
|
|||||||
@@ -313,6 +313,9 @@ pub enum FPCategory {
|
|||||||
pub trait Float: Signed
|
pub trait Float: Signed
|
||||||
+ Round
|
+ Round
|
||||||
+ Primitive {
|
+ Primitive {
|
||||||
|
fn max(self, other: Self) -> Self;
|
||||||
|
fn min(self, other: Self) -> Self;
|
||||||
|
|
||||||
// FIXME (#5527): These should be associated constants
|
// FIXME (#5527): These should be associated constants
|
||||||
fn nan() -> Self;
|
fn nan() -> Self;
|
||||||
fn infinity() -> Self;
|
fn infinity() -> Self;
|
||||||
|
|||||||
@@ -1063,7 +1063,7 @@ impl MetricMap {
|
|||||||
Some(v) => {
|
Some(v) => {
|
||||||
let delta = v.value - vold.value;
|
let delta = v.value - vold.value;
|
||||||
let noise = match noise_pct {
|
let noise = match noise_pct {
|
||||||
None => f64::max(vold.noise.abs(), v.noise.abs()),
|
None => vold.noise.abs().max(v.noise.abs()),
|
||||||
Some(pct) => vold.value * pct / 100.0
|
Some(pct) => vold.value * pct / 100.0
|
||||||
};
|
};
|
||||||
if delta.abs() <= noise {
|
if delta.abs() <= noise {
|
||||||
|
|||||||
Reference in New Issue
Block a user