Skip to content

Commit

Permalink
Merge the Round trait into the Float trait
Browse files Browse the repository at this point in the history
Move the rounding functions into the `std::num::Float` trait and then remove `std::num::Round`.

This continues the flattening of the numeric traits tracked in #10387. The aim is to make `std::num` very simple and tied to the built in types, leaving the definition of more complex numeric towers to third-party libraries.

[breaking-change]
  • Loading branch information
brendanzab committed Apr 19, 2014
1 parent b75683c commit fe47202
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 118 deletions.
75 changes: 35 additions & 40 deletions src/libnum/rational.rs
Expand Up @@ -15,7 +15,7 @@ use Integer;
use std::cmp;
use std::fmt;
use std::from_str::FromStr;
use std::num::{Zero,One,ToStrRadix,FromStrRadix,Round};
use std::num::{Zero, One, ToStrRadix, FromStrRadix};
use bigint::{BigInt, BigUint, Sign, Plus, Minus};

/// Represents the ratio between 2 numbers.
Expand Down Expand Up @@ -113,6 +113,40 @@ impl<T: Clone + Integer + Ord>
pub fn recip(&self) -> Ratio<T> {
Ratio::new_raw(self.denom.clone(), self.numer.clone())
}

pub fn floor(&self) -> Ratio<T> {
if *self < Zero::zero() {
Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
} else {
Ratio::from_integer(self.numer / self.denom)
}
}

pub fn ceil(&self) -> Ratio<T> {
if *self < Zero::zero() {
Ratio::from_integer(self.numer / self.denom)
} else {
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
}
}

#[inline]
pub fn round(&self) -> Ratio<T> {
if *self < Zero::zero() {
Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
} else {
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
}
}

#[inline]
pub fn trunc(&self) -> Ratio<T> {
Ratio::from_integer(self.numer / self.denom)
}

pub fn fract(&self) -> Ratio<T> {
Ratio::new_raw(self.numer % self.denom, self.denom.clone())
}
}

impl Ratio<BigInt> {
Expand Down Expand Up @@ -238,45 +272,6 @@ impl<T: Clone + Integer + Ord>
impl<T: Clone + Integer + Ord>
Num for Ratio<T> {}

/* Utils */
impl<T: Clone + Integer + Ord>
Round for Ratio<T> {

fn floor(&self) -> Ratio<T> {
if *self < Zero::zero() {
Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
} else {
Ratio::from_integer(self.numer / self.denom)
}
}

fn ceil(&self) -> Ratio<T> {
if *self < Zero::zero() {
Ratio::from_integer(self.numer / self.denom)
} else {
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
}
}

#[inline]
fn round(&self) -> Ratio<T> {
if *self < Zero::zero() {
Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
} else {
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
}
}

#[inline]
fn trunc(&self) -> Ratio<T> {
Ratio::from_integer(self.numer / self.denom)
}

fn fract(&self) -> Ratio<T> {
Ratio::new_raw(self.numer % self.denom, self.denom.clone())
}
}

/* String conversions */
impl<T: fmt::Show> fmt::Show for Ratio<T> {
/// Renders as `numer/denom`.
Expand Down
52 changes: 25 additions & 27 deletions src/libstd/num/f32.rs
Expand Up @@ -239,33 +239,6 @@ impl Signed for f32 {
fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY }
}

impl Round for f32 {
/// Round half-way cases toward `NEG_INFINITY`
#[inline]
fn floor(&self) -> f32 { unsafe{intrinsics::floorf32(*self)} }

/// Round half-way cases toward `INFINITY`
#[inline]
fn ceil(&self) -> f32 { unsafe{intrinsics::ceilf32(*self)} }

/// Round half-way cases away from `0.0`
#[inline]
fn round(&self) -> f32 { unsafe{intrinsics::roundf32(*self)} }

/// The integer part of the number (rounds towards `0.0`)
#[inline]
fn trunc(&self) -> f32 { unsafe{intrinsics::truncf32(*self)} }

/// The fractional part of the number, satisfying:
///
/// ```rust
/// let x = 1.65f32;
/// assert!(x == x.trunc() + x.fract())
/// ```
#[inline]
fn fract(&self) -> f32 { *self - self.trunc() }
}

impl Bounded for f32 {
#[inline]
fn min_value() -> f32 { 1.17549435e-38 }
Expand Down Expand Up @@ -414,6 +387,31 @@ impl Float for f32 {
(mantissa as u64, exponent, sign)
}

/// Round half-way cases toward `NEG_INFINITY`
#[inline]
fn floor(&self) -> f32 { unsafe{intrinsics::floorf32(*self)} }

/// Round half-way cases toward `INFINITY`
#[inline]
fn ceil(&self) -> f32 { unsafe{intrinsics::ceilf32(*self)} }

/// Round half-way cases away from `0.0`
#[inline]
fn round(&self) -> f32 { unsafe{intrinsics::roundf32(*self)} }

/// The integer part of the number (rounds towards `0.0`)
#[inline]
fn trunc(&self) -> f32 { unsafe{intrinsics::truncf32(*self)} }

/// The fractional part of the number, satisfying:
///
/// ```rust
/// let x = 1.65f32;
/// assert!(x == x.trunc() + x.fract())
/// ```
#[inline]
fn fract(&self) -> f32 { *self - self.trunc() }

/// Archimedes' constant
#[inline]
fn pi() -> f32 { 3.14159265358979323846264338327950288 }
Expand Down
52 changes: 25 additions & 27 deletions src/libstd/num/f64.rs
Expand Up @@ -247,33 +247,6 @@ impl Signed for f64 {
fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY }
}

impl Round for f64 {
/// Round half-way cases toward `NEG_INFINITY`
#[inline]
fn floor(&self) -> f64 { unsafe{intrinsics::floorf64(*self)} }

/// Round half-way cases toward `INFINITY`
#[inline]
fn ceil(&self) -> f64 { unsafe{intrinsics::ceilf64(*self)} }

/// Round half-way cases away from `0.0`
#[inline]
fn round(&self) -> f64 { unsafe{intrinsics::roundf64(*self)} }

/// The integer part of the number (rounds towards `0.0`)
#[inline]
fn trunc(&self) -> f64 { unsafe{intrinsics::truncf64(*self)} }

/// The fractional part of the number, satisfying:
///
/// ```rust
/// let x = 1.65f64;
/// assert!(x == x.trunc() + x.fract())
/// ```
#[inline]
fn fract(&self) -> f64 { *self - self.trunc() }
}

impl Bounded for f64 {
#[inline]
fn min_value() -> f64 { 2.2250738585072014e-308 }
Expand Down Expand Up @@ -420,6 +393,31 @@ impl Float for f64 {
(mantissa, exponent, sign)
}

/// Round half-way cases toward `NEG_INFINITY`
#[inline]
fn floor(&self) -> f64 { unsafe{intrinsics::floorf64(*self)} }

/// Round half-way cases toward `INFINITY`
#[inline]
fn ceil(&self) -> f64 { unsafe{intrinsics::ceilf64(*self)} }

/// Round half-way cases away from `0.0`
#[inline]
fn round(&self) -> f64 { unsafe{intrinsics::roundf64(*self)} }

/// The integer part of the number (rounds towards `0.0`)
#[inline]
fn trunc(&self) -> f64 { unsafe{intrinsics::truncf64(*self)} }

/// The fractional part of the number, satisfying:
///
/// ```rust
/// let x = 1.65f64;
/// assert!(x == x.trunc() + x.fract())
/// ```
#[inline]
fn fract(&self) -> f64 { *self - self.trunc() }

/// Archimedes' constant
#[inline]
fn pi() -> f64 { 3.14159265358979323846264338327950288 }
Expand Down
37 changes: 17 additions & 20 deletions src/libstd/num/mod.rs
Expand Up @@ -162,25 +162,6 @@ pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
/// A trait for values which cannot be negative
pub trait Unsigned: Num {}

/// A collection of rounding operations.
pub trait Round {
/// Return the largest integer less than or equal to a number.
fn floor(&self) -> Self;

/// Return the smallest integer greater than or equal to a number.
fn ceil(&self) -> Self;

/// Return the nearest integer to a number. Round half-way cases away from
/// `0.0`.
fn round(&self) -> Self;

/// Return the integer part of a number.
fn trunc(&self) -> Self;

/// Return the fractional part of a number.
fn fract(&self) -> Self;
}

/// Raises a value to the power of exp, using exponentiation by squaring.
///
/// # Example
Expand Down Expand Up @@ -347,7 +328,7 @@ pub enum FPCategory {
//
// FIXME(#8888): Several of these functions have a parameter named
// `unused_self`. Removing it requires #8888 to be fixed.
pub trait Float: Signed + Round + Primitive {
pub trait Float: Signed + Primitive {
/// Returns the maximum of the two numbers.
fn max(self, other: Self) -> Self;
/// Returns the minimum of the two numbers.
Expand Down Expand Up @@ -431,6 +412,22 @@ pub trait Float: Signed + Round + Primitive {
/// Returns the mantissa, exponent and sign as integers, respectively.
fn integer_decode(&self) -> (u64, i16, i8);

/// Return the largest integer less than or equal to a number.
fn floor(&self) -> Self;

/// Return the smallest integer greater than or equal to a number.
fn ceil(&self) -> Self;

/// Return the nearest integer to a number. Round half-way cases away from
/// `0.0`.
fn round(&self) -> Self;

/// Return the integer part of a number.
fn trunc(&self) -> Self;

/// Return the fractional part of a number.
fn fract(&self) -> Self;

/// Archimedes' constant.
fn pi() -> Self;

Expand Down
6 changes: 3 additions & 3 deletions src/libstd/num/strconv.rs
Expand Up @@ -15,7 +15,7 @@ use clone::Clone;
use container::Container;
use iter::Iterator;
use num::{NumCast, Zero, One, cast, Int};
use num::{Round, Float, FPNaN, FPInfinite, ToPrimitive};
use num::{Float, FPNaN, FPInfinite, ToPrimitive};
use num;
use ops::{Add, Sub, Mul, Div, Rem, Neg};
use option::{None, Option, Some};
Expand Down Expand Up @@ -258,7 +258,7 @@ pub fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f:
* - Fails if `radix` > 25 and `exp_format` is `ExpBin` due to conflict
* between digit and exponent sign `'p'`.
*/
pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+Round+
pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+
Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
num: T, radix: uint, negative_zero: bool,
sign: SignFormat, digits: SignificantDigits, exp_format: ExponentFormat, exp_upper: bool
Expand Down Expand Up @@ -491,7 +491,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+Round+
* `to_str_bytes_common()`, for details see there.
*/
#[inline]
pub fn float_to_str_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Float+Round+
pub fn float_to_str_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Float+
Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
num: T, radix: uint, negative_zero: bool,
sign: SignFormat, digits: SignificantDigits, exp_format: ExponentFormat, exp_capital: bool
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/prelude.rs
Expand Up @@ -45,7 +45,7 @@ pub use iter::{FromIterator, Extendable};
pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator};
pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
pub use num::{Signed, Unsigned, Round};
pub use num::{Signed, Unsigned};
pub use num::{Primitive, Int, Float, ToPrimitive, FromPrimitive};
pub use path::{GenericPath, Path, PosixPath, WindowsPath};
pub use ptr::RawPtr;
Expand Down

0 comments on commit fe47202

Please sign in to comment.