Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Signed, Unsigned and Natural traits #6041

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libcore/core.rc
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
pub use iter::{ExtendedMutableIter};

pub use num::{Num, NumCast};
pub use num::{Num, Signed, Unsigned, Natural, NumCast};
pub use ptr::Ptr;
pub use to_str::ToStr;
pub use clone::Clone;
Expand Down
114 changes: 74 additions & 40 deletions src/libcore/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! Operations and constants for `f32`

use num::strconv;
use num::Signed;
use num;
use option::Option;
use from_str;
Expand Down Expand Up @@ -163,38 +164,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 a positive number, including +0.0f320 and +Infinity
#[inline(always)]
pub fn is_positive(x: f32) -> bool {
x > 0.0f32 || (1.0f32/x) == infinity
}

/// Returns true if `x` is a negative number, including -0.0f320 and -Infinity
#[inline(always)]
pub fn is_negative(x: f32) -> bool {
x < 0.0f32 || (1.0f32/x) == neg_infinity
}

/**
* Returns true if `x` is a negative number, including -0.0f320 and -Infinity
*
* This is the same as `f32::is_negative`.
*/
#[inline(always)]
pub fn is_nonpositive(x: f32) -> bool {
return x < 0.0f32 || (1.0f32/x) == neg_infinity;
}

/**
* Returns true if `x` is a positive number, including +0.0f320 and +Infinity
*
* This is the same as `f32::is_positive`.)
*/
#[inline(always)]
pub fn is_nonnegative(x: f32) -> bool {
return x > 0.0f32 || (1.0f32/x) == infinity;
}

/// Returns true if `x` is a zero number (positive or negative zero)
#[inline(always)]
pub fn is_zero(x: f32) -> bool {
Expand Down Expand Up @@ -259,11 +228,6 @@ pub mod consts {
pub static ln_10: f32 = 2.30258509299404568401799145468436421_f32;
}

#[inline(always)]
pub fn signbit(x: f32) -> int {
if is_negative(x) { return 1; } else { return 0; }
}

#[inline(always)]
pub fn logarithm(n: f32, b: f32) -> f32 {
return log2(n) / log2(b);
Expand Down Expand Up @@ -351,15 +315,41 @@ impl Neg<f32> for f32 {
fn neg(&self) -> f32 { -*self }
}

impl Signed for f32 {
/// Computes the absolute value. Returns `NaN` if the number is `NaN`.
#[inline(always)]
fn abs(&self) -> f32 { abs(*self) }

/**
* # Returns
*
* - `1.0` if the number is positive, `+0.0` or `infinity`
* - `-1.0` if the number is negative, `-0.0` or `neg_infinity`
* - `NaN` if the number is `NaN`
*/
#[inline(always)]
fn signum(&self) -> f32 {
if is_NaN(*self) { NaN } else { copysign(1.0, *self) }
}

/// Returns `true` if the number is positive, including `+0.0` and `infinity`
#[inline(always)]
fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity }

/// Returns `true` if the number is negative, including `-0.0` and `neg_infinity`
#[inline(always)]
fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
}

impl num::Round for f32 {
#[inline(always)]
fn round(&self, mode: num::RoundMode) -> f32 {
match mode {
num::RoundDown => floor(*self),
num::RoundUp => ceil(*self),
num::RoundToZero if is_negative(*self) => ceil(*self),
num::RoundToZero if self.is_negative() => ceil(*self),
num::RoundToZero => floor(*self),
num::RoundFromZero if is_negative(*self) => floor(*self),
num::RoundFromZero if self.is_negative() => floor(*self),
num::RoundFromZero => ceil(*self)
}
}
Expand All @@ -370,7 +360,7 @@ impl num::Round for f32 {
fn ceil(&self) -> f32 { ceil(*self) }
#[inline(always)]
fn fract(&self) -> f32 {
if is_negative(*self) {
if self.is_negative() {
(*self) - ceil(*self)
} else {
(*self) - floor(*self)
Expand Down Expand Up @@ -595,6 +585,50 @@ impl num::FromStrRadix for f32 {
}
}

#[cfg(test)]
mod tests {
use f32::*;

#[test]
pub fn test_signed() {
assert_eq!(infinity.abs(), infinity);
assert_eq!(1f32.abs(), 1f32);
assert_eq!(0f32.abs(), 0f32);
assert_eq!((-0f32).abs(), 0f32);
assert_eq!((-1f32).abs(), 1f32);
assert_eq!(neg_infinity.abs(), infinity);
assert_eq!((1f32/neg_infinity).abs(), 0f32);
assert!(is_NaN(NaN.abs()));

assert_eq!(infinity.signum(), 1f32);
assert_eq!(1f32.signum(), 1f32);
assert_eq!(0f32.signum(), 1f32);
assert_eq!((-0f32).signum(), -1f32);
assert_eq!((-1f32).signum(), -1f32);
assert_eq!(neg_infinity.signum(), -1f32);
assert_eq!((1f32/neg_infinity).signum(), -1f32);
assert!(is_NaN(NaN.signum()));

assert!(infinity.is_positive());
assert!(1f32.is_positive());
assert!(0f32.is_positive());
assert!(!(-0f32).is_positive());
assert!(!(-1f32).is_positive());
assert!(!neg_infinity.is_positive());
assert!(!(1f32/neg_infinity).is_positive());
assert!(!NaN.is_positive());

assert!(!infinity.is_negative());
assert!(!1f32.is_negative());
assert!(!0f32.is_negative());
assert!((-0f32).is_negative());
assert!((-1f32).is_negative());
assert!(neg_infinity.is_negative());
assert!((1f32/neg_infinity).is_negative());
assert!(!NaN.is_negative());
}
}

//
// Local Variables:
// mode: rust
Expand Down
112 changes: 74 additions & 38 deletions src/libcore/num/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! Operations and constants for `f64`

use num::strconv;
use num::Signed;
use num;
use option::Option;
use to_str;
Expand Down Expand Up @@ -183,36 +184,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 a positive number, including +0.0f640 and +Infinity
#[inline(always)]
pub fn is_positive(x: f64) -> bool
{ return x > 0.0f64 || (1.0f64/x) == infinity; }

/// Returns true if `x` is a negative number, including -0.0f640 and -Infinity
#[inline(always)]
pub fn is_negative(x: f64) -> bool
{ return x < 0.0f64 || (1.0f64/x) == neg_infinity; }

/**
* Returns true if `x` is a negative number, including -0.0f640 and -Infinity
*
* This is the same as `f64::is_negative`.
*/
#[inline(always)]
pub fn is_nonpositive(x: f64) -> bool {
return x < 0.0f64 || (1.0f64/x) == neg_infinity;
}

/**
* Returns true if `x` is a positive number, including +0.0f640 and +Infinity
*
* This is the same as `f64::positive`.
*/
#[inline(always)]
pub fn is_nonnegative(x: f64) -> bool {
return x > 0.0f64 || (1.0f64/x) == infinity;
}

/// Returns true if `x` is a zero number (positive or negative zero)
#[inline(always)]
pub fn is_zero(x: f64) -> bool {
Expand Down Expand Up @@ -278,11 +249,6 @@ pub mod consts {
pub static ln_10: f64 = 2.30258509299404568401799145468436421_f64;
}

#[inline(always)]
pub fn signbit(x: f64) -> int {
if is_negative(x) { return 1; } else { return 0; }
}

#[inline(always)]
pub fn logarithm(n: f64, b: f64) -> f64 {
return log2(n) / log2(b);
Expand Down Expand Up @@ -357,15 +323,41 @@ impl Neg<f64> for f64 {
fn neg(&self) -> f64 { -*self }
}

impl Signed for f64 {
/// Computes the absolute value. Returns `NaN` if the number is `NaN`.
#[inline(always)]
fn abs(&self) -> f64 { abs(*self) }

/**
* # Returns
*
* - `1.0` if the number is positive, `+0.0` or `infinity`
* - `-1.0` if the number is negative, `-0.0` or `neg_infinity`
* - `NaN` if the number is `NaN`
*/
#[inline(always)]
fn signum(&self) -> f64 {
if is_NaN(*self) { NaN } else { copysign(1.0, *self) }
}

/// Returns `true` if the number is positive, including `+0.0` and `infinity`
#[inline(always)]
fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity }

/// Returns `true` if the number is negative, including `-0.0` and `neg_infinity`
#[inline(always)]
fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
}

impl num::Round for f64 {
#[inline(always)]
fn round(&self, mode: num::RoundMode) -> f64 {
match mode {
num::RoundDown => floor(*self),
num::RoundUp => ceil(*self),
num::RoundToZero if is_negative(*self) => ceil(*self),
num::RoundToZero if self.is_negative() => ceil(*self),
num::RoundToZero => floor(*self),
num::RoundFromZero if is_negative(*self) => floor(*self),
num::RoundFromZero if self.is_negative() => floor(*self),
num::RoundFromZero => ceil(*self)
}
}
Expand All @@ -376,7 +368,7 @@ impl num::Round for f64 {
fn ceil(&self) -> f64 { ceil(*self) }
#[inline(always)]
fn fract(&self) -> f64 {
if is_negative(*self) {
if self.is_negative() {
(*self) - ceil(*self)
} else {
(*self) - floor(*self)
Expand Down Expand Up @@ -601,6 +593,50 @@ impl num::FromStrRadix for f64 {
}
}

#[cfg(test)]
mod tests {
use f64::*;

#[test]
pub fn test_signed() {
assert_eq!(infinity.abs(), infinity);
assert_eq!(1f64.abs(), 1f64);
assert_eq!(0f64.abs(), 0f64);
assert_eq!((-0f64).abs(), 0f64);
assert_eq!((-1f64).abs(), 1f64);
assert_eq!(neg_infinity.abs(), infinity);
assert_eq!((1f64/neg_infinity).abs(), 0f64);
assert!(is_NaN(NaN.abs()));

assert_eq!(infinity.signum(), 1f64);
assert_eq!(1f64.signum(), 1f64);
assert_eq!(0f64.signum(), 1f64);
assert_eq!((-0f64).signum(), -1f64);
assert_eq!((-1f64).signum(), -1f64);
assert_eq!(neg_infinity.signum(), -1f64);
assert_eq!((1f64/neg_infinity).signum(), -1f64);
assert!(is_NaN(NaN.signum()));

assert!(infinity.is_positive());
assert!(1f64.is_positive());
assert!(0f64.is_positive());
assert!(!(-0f64).is_positive());
assert!(!(-1f64).is_positive());
assert!(!neg_infinity.is_positive());
assert!(!(1f64/neg_infinity).is_positive());
assert!(!NaN.is_positive());

assert!(!infinity.is_negative());
assert!(!1f64.is_negative());
assert!(!0f64.is_negative());
assert!((-0f64).is_negative());
assert!((-1f64).is_negative());
assert!(neg_infinity.is_negative());
assert!((1f64/neg_infinity).is_negative());
assert!(!NaN.is_negative());
}
}

//
// Local Variables:
// mode: rust
Expand Down
Loading