Merge the Round trait into the Float trait
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]
This commit is contained in:
parent
b75683cadf
commit
fe47202034
@ -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.
|
||||
@ -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> {
|
||||
@ -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`.
|
||||
|
@ -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 }
|
||||
@ -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 }
|
||||
|
@ -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 }
|
||||
@ -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 }
|
||||
|
@ -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
|
||||
@ -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.
|
||||
@ -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;
|
||||
|
||||
|
@ -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};
|
||||
@ -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
|
||||
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user