Add Int, Uint and Float traits for primitive numbers
This commit is contained in:
parent
b62421000c
commit
4c07f5e457
@ -108,6 +108,7 @@ pub use num::{Signed, Unsigned, Integer};
|
||||
pub use num::{Round, Fractional, Real, RealExt};
|
||||
pub use num::{Bitwise, Bounded};
|
||||
pub use num::{Primitive, PrimitiveInt};
|
||||
pub use num::{Int, Uint, Float};
|
||||
pub use ptr::Ptr;
|
||||
pub use to_str::ToStr;
|
||||
pub use clone::Clone;
|
||||
|
@ -114,9 +114,6 @@ pub static infinity: f32 = 1.0_f32/0.0_f32;
|
||||
|
||||
pub static neg_infinity: f32 = -1.0_f32/0.0_f32;
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_NaN(f: f32) -> bool { f != f }
|
||||
|
||||
#[inline(always)]
|
||||
pub fn add(x: f32, y: f32) -> f32 { return x + y; }
|
||||
|
||||
@ -154,18 +151,6 @@ pub fn gt(x: f32, y: f32) -> bool { return x > y; }
|
||||
// FIXME (#1999): replace the predicates below with llvm intrinsics or
|
||||
// calls to the libmath macros in the rust runtime for performance.
|
||||
|
||||
/// Returns true if `x`is an infinite number
|
||||
#[inline(always)]
|
||||
pub fn is_infinite(x: f32) -> bool {
|
||||
return x == infinity || x == neg_infinity;
|
||||
}
|
||||
|
||||
/// Returns true if `x`is a finite number
|
||||
#[inline(always)]
|
||||
pub fn is_finite(x: f32) -> bool {
|
||||
return !(is_NaN(x) || is_infinite(x));
|
||||
}
|
||||
|
||||
// FIXME (#1999): add is_normal, is_subnormal, and fpclassify.
|
||||
|
||||
/* Module: consts */
|
||||
@ -313,7 +298,7 @@ impl Signed for f32 {
|
||||
///
|
||||
#[inline(always)]
|
||||
fn signum(&self) -> f32 {
|
||||
if is_NaN(*self) { NaN } else { copysign(1.0, *self) }
|
||||
if self.is_NaN() { NaN } else { copysign(1.0, *self) }
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is positive, including `+0.0` and `infinity`
|
||||
@ -517,6 +502,35 @@ impl Primitive for f32 {
|
||||
fn bytes() -> uint { Primitive::bits::<f32>() / 8 }
|
||||
}
|
||||
|
||||
impl Float for f32 {
|
||||
#[inline(always)]
|
||||
fn NaN() -> f32 { 0.0 / 0.0 }
|
||||
|
||||
#[inline(always)]
|
||||
fn infinity() -> f32 { 1.0 / 0.0 }
|
||||
|
||||
#[inline(always)]
|
||||
fn neg_infinity() -> f32 { -1.0 / 0.0 }
|
||||
|
||||
#[inline(always)]
|
||||
fn neg_zero() -> f32 { -0.0 }
|
||||
|
||||
#[inline(always)]
|
||||
fn is_NaN(&self) -> bool { *self != *self }
|
||||
|
||||
/// Returns `true` if the number is infinite
|
||||
#[inline(always)]
|
||||
fn is_infinite(&self) -> bool {
|
||||
*self == Float::infinity() || *self == Float::neg_infinity()
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is finite
|
||||
#[inline(always)]
|
||||
fn is_finite(&self) -> bool {
|
||||
!(self.is_NaN() || self.is_infinite())
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Section: String Conversions
|
||||
//
|
||||
@ -852,7 +866,7 @@ mod tests {
|
||||
assert_eq!((-1f32).abs(), 1f32);
|
||||
assert_eq!(neg_infinity.abs(), infinity);
|
||||
assert_eq!((1f32/neg_infinity).abs(), 0f32);
|
||||
assert!(is_NaN(NaN.abs()));
|
||||
assert!(NaN.abs().is_NaN());
|
||||
|
||||
assert_eq!(infinity.signum(), 1f32);
|
||||
assert_eq!(1f32.signum(), 1f32);
|
||||
@ -861,7 +875,7 @@ mod tests {
|
||||
assert_eq!((-1f32).signum(), -1f32);
|
||||
assert_eq!(neg_infinity.signum(), -1f32);
|
||||
assert_eq!((1f32/neg_infinity).signum(), -1f32);
|
||||
assert!(is_NaN(NaN.signum()));
|
||||
assert!(NaN.signum().is_NaN());
|
||||
|
||||
assert!(infinity.is_positive());
|
||||
assert!(1f32.is_positive());
|
||||
|
@ -138,9 +138,6 @@ pub static infinity: f64 = 1.0_f64/0.0_f64;
|
||||
|
||||
pub static neg_infinity: f64 = -1.0_f64/0.0_f64;
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_NaN(f: f64) -> bool { f != f }
|
||||
|
||||
#[inline(always)]
|
||||
pub fn add(x: f64, y: f64) -> f64 { return x + y; }
|
||||
|
||||
@ -174,18 +171,6 @@ pub fn ge(x: f64, y: f64) -> bool { return x >= y; }
|
||||
#[inline(always)]
|
||||
pub fn gt(x: f64, y: f64) -> bool { return x > y; }
|
||||
|
||||
/// Returns true if `x`is an infinite number
|
||||
#[inline(always)]
|
||||
pub fn is_infinite(x: f64) -> bool {
|
||||
return x == infinity || x == neg_infinity;
|
||||
}
|
||||
|
||||
/// Returns true if `x` is a finite number
|
||||
#[inline(always)]
|
||||
pub fn is_finite(x: f64) -> bool {
|
||||
return !(is_NaN(x) || is_infinite(x));
|
||||
}
|
||||
|
||||
|
||||
// FIXME (#1999): add is_normal, is_subnormal, and fpclassify
|
||||
|
||||
@ -323,7 +308,7 @@ impl Signed for f64 {
|
||||
///
|
||||
#[inline(always)]
|
||||
fn signum(&self) -> f64 {
|
||||
if is_NaN(*self) { NaN } else { copysign(1.0, *self) }
|
||||
if self.is_NaN() { NaN } else { copysign(1.0, *self) }
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is positive, including `+0.0` and `infinity`
|
||||
@ -557,6 +542,35 @@ impl Primitive for f64 {
|
||||
fn bytes() -> uint { Primitive::bits::<f64>() / 8 }
|
||||
}
|
||||
|
||||
impl Float for f64 {
|
||||
#[inline(always)]
|
||||
fn NaN() -> f64 { 0.0 / 0.0 }
|
||||
|
||||
#[inline(always)]
|
||||
fn infinity() -> f64 { 1.0 / 0.0 }
|
||||
|
||||
#[inline(always)]
|
||||
fn neg_infinity() -> f64 { -1.0 / 0.0 }
|
||||
|
||||
#[inline(always)]
|
||||
fn neg_zero() -> f64 { -0.0 }
|
||||
|
||||
#[inline(always)]
|
||||
fn is_NaN(&self) -> bool { *self != *self }
|
||||
|
||||
/// Returns `true` if the number is infinite
|
||||
#[inline(always)]
|
||||
fn is_infinite(&self) -> bool {
|
||||
*self == Float::infinity() || *self == Float::neg_infinity()
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is finite
|
||||
#[inline(always)]
|
||||
fn is_finite(&self) -> bool {
|
||||
!(self.is_NaN() || self.is_infinite())
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Section: String Conversions
|
||||
//
|
||||
@ -893,7 +907,7 @@ mod tests {
|
||||
assert_eq!((-1f64).abs(), 1f64);
|
||||
assert_eq!(neg_infinity.abs(), infinity);
|
||||
assert_eq!((1f64/neg_infinity).abs(), 0f64);
|
||||
assert!(is_NaN(NaN.abs()));
|
||||
assert!(NaN.abs().is_NaN());
|
||||
|
||||
assert_eq!(infinity.signum(), 1f64);
|
||||
assert_eq!(1f64.signum(), 1f64);
|
||||
@ -902,7 +916,7 @@ mod tests {
|
||||
assert_eq!((-1f64).signum(), -1f64);
|
||||
assert_eq!(neg_infinity.signum(), -1f64);
|
||||
assert_eq!((1f64/neg_infinity).signum(), -1f64);
|
||||
assert!(is_NaN(NaN.signum()));
|
||||
assert!(NaN.signum().is_NaN());
|
||||
|
||||
assert!(infinity.is_positive());
|
||||
assert!(1f64.is_positive());
|
||||
|
@ -337,13 +337,6 @@ pub fn pow_with_uint(base: uint, pow: uint) -> float {
|
||||
return total;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_infinite(x: float) -> bool { f64::is_infinite(x as f64) }
|
||||
#[inline(always)]
|
||||
pub fn is_finite(x: float) -> bool { f64::is_finite(x as f64) }
|
||||
#[inline(always)]
|
||||
pub fn is_NaN(x: float) -> bool { f64::is_NaN(x as f64) }
|
||||
|
||||
#[inline(always)]
|
||||
pub fn abs(x: float) -> float {
|
||||
f64::abs(x as f64) as float
|
||||
@ -677,7 +670,7 @@ impl Signed for float {
|
||||
///
|
||||
#[inline(always)]
|
||||
fn signum(&self) -> float {
|
||||
if is_NaN(*self) { NaN } else { f64::copysign(1.0, *self as f64) as float }
|
||||
if self.is_NaN() { NaN } else { f64::copysign(1.0, *self as f64) as float }
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is positive, including `+0.0` and `infinity`
|
||||
@ -697,6 +690,35 @@ impl Primitive for float {
|
||||
fn bytes() -> uint { Primitive::bytes::<f64>() }
|
||||
}
|
||||
|
||||
impl Float for float {
|
||||
#[inline(always)]
|
||||
fn NaN() -> float { 0.0 / 0.0 }
|
||||
|
||||
#[inline(always)]
|
||||
fn infinity() -> float { 1.0 / 0.0 }
|
||||
|
||||
#[inline(always)]
|
||||
fn neg_infinity() -> float { -1.0 / 0.0 }
|
||||
|
||||
#[inline(always)]
|
||||
fn neg_zero() -> float { -0.0 }
|
||||
|
||||
#[inline(always)]
|
||||
fn is_NaN(&self) -> bool { *self != *self }
|
||||
|
||||
/// Returns `true` if the number is infinite
|
||||
#[inline(always)]
|
||||
fn is_infinite(&self) -> bool {
|
||||
*self == Float::infinity() || *self == Float::neg_infinity()
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is finite
|
||||
#[inline(always)]
|
||||
fn is_finite(&self) -> bool {
|
||||
!(self.is_NaN() || self.is_infinite())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -814,7 +836,7 @@ mod tests {
|
||||
assert_eq!((-1f).abs(), 1f);
|
||||
assert_eq!(neg_infinity.abs(), infinity);
|
||||
assert_eq!((1f/neg_infinity).abs(), 0f);
|
||||
assert!(is_NaN(NaN.abs()));
|
||||
assert!(NaN.abs().is_NaN());
|
||||
|
||||
assert_eq!(infinity.signum(), 1f);
|
||||
assert_eq!(1f.signum(), 1f);
|
||||
@ -823,7 +845,7 @@ mod tests {
|
||||
assert_eq!((-1f).signum(), -1f);
|
||||
assert_eq!(neg_infinity.signum(), -1f);
|
||||
assert_eq!((1f/neg_infinity).signum(), -1f);
|
||||
assert!(is_NaN(NaN.signum()));
|
||||
assert!(NaN.signum().is_NaN());
|
||||
|
||||
assert!(infinity.is_positive());
|
||||
assert!(1f.is_positive());
|
||||
@ -878,7 +900,7 @@ mod tests {
|
||||
assert_eq!(from_str(~"-inf"), Some(neg_infinity));
|
||||
// note: NaN != NaN, hence this slightly complex test
|
||||
match from_str(~"NaN") {
|
||||
Some(f) => assert!(is_NaN(f)),
|
||||
Some(f) => assert!(f.is_NaN()),
|
||||
None => fail!()
|
||||
}
|
||||
// note: -0 == 0, hence these slightly more complex tests
|
||||
@ -925,7 +947,7 @@ mod tests {
|
||||
assert_eq!(from_str_hex(~"-inf"), Some(neg_infinity));
|
||||
// note: NaN != NaN, hence this slightly complex test
|
||||
match from_str_hex(~"NaN") {
|
||||
Some(f) => assert!(is_NaN(f)),
|
||||
Some(f) => assert!(f.is_NaN()),
|
||||
None => fail!()
|
||||
}
|
||||
// note: -0 == 0, hence these slightly more complex tests
|
||||
|
@ -447,6 +447,8 @@ impl Bounded for T {
|
||||
|
||||
impl PrimitiveInt for T {}
|
||||
|
||||
impl Int for T {}
|
||||
|
||||
// String conversion functions and impl str -> num
|
||||
|
||||
/// Parse a string as a number in base 10.
|
||||
|
@ -228,6 +228,24 @@ pub trait Uint: PrimitiveInt
|
||||
pub trait Int: PrimitiveInt
|
||||
+ Signed {}
|
||||
|
||||
///
|
||||
/// Primitive floating point numbers. This trait should only be implemented
|
||||
/// for the `f32`, `f64`, and `float` types.
|
||||
///
|
||||
pub trait Float: Real
|
||||
+ Signed
|
||||
+ Primitive {
|
||||
// FIXME (#5527): These should be associated constants
|
||||
fn NaN() -> Self;
|
||||
fn infinity() -> Self;
|
||||
fn neg_infinity() -> Self;
|
||||
fn neg_zero() -> Self;
|
||||
|
||||
fn is_NaN(&self) -> bool;
|
||||
fn is_infinite(&self) -> bool;
|
||||
fn is_finite(&self) -> bool;
|
||||
}
|
||||
|
||||
///
|
||||
/// Cast from one machine scalar to another
|
||||
///
|
||||
|
@ -279,6 +279,8 @@ impl Bounded for T {
|
||||
|
||||
impl PrimitiveInt for T {}
|
||||
|
||||
impl Uint for T {}
|
||||
|
||||
// String conversion functions and impl str -> num
|
||||
|
||||
/// Parse a string as a number in base 10.
|
||||
|
@ -42,6 +42,7 @@ pub use num::{Signed, Unsigned, Integer};
|
||||
pub use num::{Round, Fractional, Real, RealExt};
|
||||
pub use num::{Bitwise, Bounded};
|
||||
pub use num::{Primitive, PrimitiveInt};
|
||||
pub use num::{Int, Uint, Float};
|
||||
pub use path::GenericPath;
|
||||
pub use path::Path;
|
||||
pub use path::PosixPath;
|
||||
|
Loading…
Reference in New Issue
Block a user