auto merge of #20573 : huonw/rust/num-stab-2, r=alexcrichton

cc #19260 

Open questions:

- I still feel weird about marking functions like `exp` as `#[stable]` in `core` since they're highly likely to call into libm which is theoretically something core is designed to avoid and so we may be forced/want to move it at some point in the future, and so it feels like a lie to call it `#[stable]` (I know `core` is `#[experimental]`, but still...)
- `abs_sub` is a horrible name IMO: it feels like it is `(a - b).abs()`, but it is actually `(a - b).max(0.)`. maybe something along the lines of `pos_diff` ("positive difference") is better.
- the associated-function nature of `Int::from_be` and `Int::from_le` feel strange to me, it feels like they should be methods, but I cannot think of a good name.

I'm also not hugely in favour of `ldexp` and `frexp` but the precedent from C is large. (e.g. AFAICT,  `ldexp` must mean "load exponent" which is essentially what it does... but only for a subset of its inputs.)
This commit is contained in:
bors 2015-01-06 13:30:29 +00:00
commit 8efd9901b6
10 changed files with 581 additions and 94 deletions

View File

@ -22,12 +22,12 @@ use num::Float;
use num::FpCategory as Fp;
use option::Option;
#[stable]
#[unstable = "pending integer conventions"]
pub const RADIX: uint = 2u;
#[stable]
#[unstable = "pending integer conventions"]
pub const MANTISSA_DIGITS: uint = 24u;
#[stable]
#[unstable = "pending integer conventions"]
pub const DIGITS: uint = 6u;
#[stable]
@ -43,14 +43,14 @@ pub const MIN_POS_VALUE: f32 = 1.17549435e-38_f32;
#[stable]
pub const MAX_VALUE: f32 = 3.40282347e+38_f32;
#[stable]
#[unstable = "pending integer conventions"]
pub const MIN_EXP: int = -125;
#[stable]
#[unstable = "pending integer conventions"]
pub const MAX_EXP: int = 128;
#[stable]
#[unstable = "pending integer conventions"]
pub const MIN_10_EXP: int = -37;
#[stable]
#[unstable = "pending integer conventions"]
pub const MAX_10_EXP: int = 38;
#[stable]
@ -177,33 +177,43 @@ impl Float for f32 {
}
#[inline]
#[deprecated]
fn mantissa_digits(_: Option<f32>) -> uint { MANTISSA_DIGITS }
#[inline]
#[deprecated]
fn digits(_: Option<f32>) -> uint { DIGITS }
#[inline]
#[deprecated]
fn epsilon() -> f32 { EPSILON }
#[inline]
#[deprecated]
fn min_exp(_: Option<f32>) -> int { MIN_EXP }
#[inline]
#[deprecated]
fn max_exp(_: Option<f32>) -> int { MAX_EXP }
#[inline]
#[deprecated]
fn min_10_exp(_: Option<f32>) -> int { MIN_10_EXP }
#[inline]
#[deprecated]
fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP }
#[inline]
#[deprecated]
fn min_value() -> f32 { MIN_VALUE }
#[inline]
#[deprecated]
fn min_pos_value(_: Option<f32>) -> f32 { MIN_POS_VALUE }
#[inline]
#[deprecated]
fn max_value() -> f32 { MAX_VALUE }
/// Returns the mantissa, exponent and sign as integers.

View File

@ -26,12 +26,11 @@ use option::Option;
// constants are implemented in favour of referencing the respective
// members of `Bounded` and `Float`.
#[stable]
#[unstable = "pending integer conventions"]
pub const RADIX: uint = 2u;
#[stable]
pub const MANTISSA_DIGITS: uint = 53u;
#[stable]
#[unstable = "pending integer conventions"]
pub const DIGITS: uint = 15u;
#[stable]
@ -47,14 +46,14 @@ pub const MIN_POS_VALUE: f64 = 2.2250738585072014e-308_f64;
#[stable]
pub const MAX_VALUE: f64 = 1.7976931348623157e+308_f64;
#[stable]
#[unstable = "pending integer conventions"]
pub const MIN_EXP: int = -1021;
#[stable]
#[unstable = "pending integer conventions"]
pub const MAX_EXP: int = 1024;
#[stable]
#[unstable = "pending integer conventions"]
pub const MIN_10_EXP: int = -307;
#[stable]
#[unstable = "pending integer conventions"]
pub const MAX_10_EXP: int = 308;
#[stable]
@ -185,33 +184,43 @@ impl Float for f64 {
}
#[inline]
#[deprecated]
fn mantissa_digits(_: Option<f64>) -> uint { MANTISSA_DIGITS }
#[inline]
#[deprecated]
fn digits(_: Option<f64>) -> uint { DIGITS }
#[inline]
#[deprecated]
fn epsilon() -> f64 { EPSILON }
#[inline]
#[deprecated]
fn min_exp(_: Option<f64>) -> int { MIN_EXP }
#[inline]
#[deprecated]
fn max_exp(_: Option<f64>) -> int { MAX_EXP }
#[inline]
#[deprecated]
fn min_10_exp(_: Option<f64>) -> int { MIN_10_EXP }
#[inline]
#[deprecated]
fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP }
#[inline]
#[deprecated]
fn min_value() -> f64 { MIN_VALUE }
#[inline]
#[deprecated]
fn min_pos_value(_: Option<f64>) -> f64 { MIN_POS_VALUE }
#[inline]
#[deprecated]
fn max_value() -> f64 { MAX_VALUE }
/// Returns the mantissa, exponent and sign as integers.

View File

@ -30,7 +30,7 @@ use option::Option::{Some, None};
use str::{FromStr, StrExt};
/// A built-in signed or unsigned integer.
#[unstable = "recently settled as part of numerics reform"]
#[stable]
pub trait Int
: Copy + Clone
+ NumCast
@ -50,18 +50,22 @@ pub trait Int
{
/// Returns the `0` value of this integer type.
// FIXME (#5527): Should be an associated constant
#[unstable = "unsure about its place in the world"]
fn zero() -> Self;
/// Returns the `1` value of this integer type.
// FIXME (#5527): Should be an associated constant
#[unstable = "unsure about its place in the world"]
fn one() -> Self;
/// Returns the smallest value that can be represented by this integer type.
// FIXME (#5527): Should be and associated constant
#[unstable = "unsure about its place in the world"]
fn min_value() -> Self;
/// Returns the largest value that can be represented by this integer type.
// FIXME (#5527): Should be and associated constant
#[unstable = "unsure about its place in the world"]
fn max_value() -> Self;
/// Returns the number of ones in the binary representation of `self`.
@ -75,6 +79,7 @@ pub trait Int
///
/// assert_eq!(n.count_ones(), 3);
/// ```
#[unstable = "pending integer conventions"]
fn count_ones(self) -> uint;
/// Returns the number of zeros in the binary representation of `self`.
@ -88,6 +93,7 @@ pub trait Int
///
/// assert_eq!(n.count_zeros(), 5);
/// ```
#[unstable = "pending integer conventions"]
#[inline]
fn count_zeros(self) -> uint {
(!self).count_ones()
@ -105,6 +111,7 @@ pub trait Int
///
/// assert_eq!(n.leading_zeros(), 10);
/// ```
#[unstable = "pending integer conventions"]
fn leading_zeros(self) -> uint;
/// Returns the number of trailing zeros in the binary representation
@ -119,6 +126,7 @@ pub trait Int
///
/// assert_eq!(n.trailing_zeros(), 3);
/// ```
#[unstable = "pending integer conventions"]
fn trailing_zeros(self) -> uint;
/// Shifts the bits to the left by a specified amount amount, `n`, wrapping
@ -134,6 +142,7 @@ pub trait Int
///
/// assert_eq!(n.rotate_left(12), m);
/// ```
#[unstable = "pending integer conventions"]
fn rotate_left(self, n: uint) -> Self;
/// Shifts the bits to the right by a specified amount amount, `n`, wrapping
@ -149,6 +158,7 @@ pub trait Int
///
/// assert_eq!(n.rotate_right(12), m);
/// ```
#[unstable = "pending integer conventions"]
fn rotate_right(self, n: uint) -> Self;
/// Reverses the byte order of the integer.
@ -163,6 +173,7 @@ pub trait Int
///
/// assert_eq!(n.swap_bytes(), m);
/// ```
#[stable]
fn swap_bytes(self) -> Self;
/// Convert an integer from big endian to the target's endianness.
@ -182,6 +193,7 @@ pub trait Int
/// assert_eq!(Int::from_be(n), n.swap_bytes())
/// }
/// ```
#[stable]
#[inline]
fn from_be(x: Self) -> Self {
if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
@ -204,6 +216,7 @@ pub trait Int
/// assert_eq!(Int::from_le(n), n.swap_bytes())
/// }
/// ```
#[stable]
#[inline]
fn from_le(x: Self) -> Self {
if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
@ -226,6 +239,7 @@ pub trait Int
/// assert_eq!(n.to_be(), n.swap_bytes())
/// }
/// ```
#[stable]
#[inline]
fn to_be(self) -> Self { // or not to be?
if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
@ -248,6 +262,7 @@ pub trait Int
/// assert_eq!(n.to_le(), n.swap_bytes())
/// }
/// ```
#[stable]
#[inline]
fn to_le(self) -> Self {
if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
@ -264,6 +279,7 @@ pub trait Int
/// assert_eq!(5u16.checked_add(65530), Some(65535));
/// assert_eq!(6u16.checked_add(65530), None);
/// ```
#[stable]
fn checked_add(self, other: Self) -> Option<Self>;
/// Checked integer subtraction. Computes `self - other`, returning `None`
@ -277,6 +293,7 @@ pub trait Int
/// assert_eq!((-127i8).checked_sub(1), Some(-128));
/// assert_eq!((-128i8).checked_sub(1), None);
/// ```
#[stable]
fn checked_sub(self, other: Self) -> Option<Self>;
/// Checked integer multiplication. Computes `self * other`, returning
@ -290,6 +307,7 @@ pub trait Int
/// assert_eq!(5u8.checked_mul(51), Some(255));
/// assert_eq!(5u8.checked_mul(52), None);
/// ```
#[stable]
fn checked_mul(self, other: Self) -> Option<Self>;
/// Checked integer division. Computes `self / other`, returning `None` if
@ -304,11 +322,12 @@ pub trait Int
/// assert_eq!((-128i8).checked_div(-1), None);
/// assert_eq!((1i8).checked_div(0), None);
/// ```
#[inline]
#[stable]
fn checked_div(self, other: Self) -> Option<Self>;
/// Saturating integer addition. Computes `self + other`, saturating at
/// the numeric bounds instead of overflowing.
#[stable]
#[inline]
fn saturating_add(self, other: Self) -> Self {
match self.checked_add(other) {
@ -320,6 +339,7 @@ pub trait Int
/// Saturating integer subtraction. Computes `self - other`, saturating at
/// the numeric bounds instead of overflowing.
#[stable]
#[inline]
fn saturating_sub(self, other: Self) -> Self {
match self.checked_sub(other) {
@ -338,6 +358,7 @@ pub trait Int
///
/// assert_eq!(2i.pow(4), 16);
/// ```
#[unstable = "pending integer conventions"]
#[inline]
fn pow(self, mut exp: uint) -> Self {
let mut base = self;
@ -369,7 +390,7 @@ macro_rules! uint_impl {
$add_with_overflow:path,
$sub_with_overflow:path,
$mul_with_overflow:path) => {
#[unstable = "trait is unstable"]
#[stable]
impl Int for $T {
#[inline]
fn zero() -> $T { 0 }
@ -500,7 +521,7 @@ macro_rules! int_impl {
$add_with_overflow:path,
$sub_with_overflow:path,
$mul_with_overflow:path) => {
#[unstable = "trait is unstable"]
#[stable]
impl Int for $T {
#[inline]
fn zero() -> $T { 0 }
@ -593,13 +614,14 @@ int_impl! { int = i64, u64, 64,
intrinsics::i64_mul_with_overflow }
/// A built-in two's complement integer.
#[unstable = "recently settled as part of numerics reform"]
#[stable]
pub trait SignedInt
: Int
+ Neg<Output=Self>
{
/// Computes the absolute value of `self`. `Int::min_value()` will be
/// returned if the number is `Int::min_value()`.
#[unstable = "overflow in debug builds?"]
fn abs(self) -> Self;
/// Returns a number representing sign of `self`.
@ -607,19 +629,23 @@ pub trait SignedInt
/// - `0` if the number is zero
/// - `1` if the number is positive
/// - `-1` if the number is negative
#[stable]
fn signum(self) -> Self;
/// Returns `true` if `self` is positive and `false` if the number
/// is zero or negative.
#[stable]
fn is_positive(self) -> bool;
/// Returns `true` if `self` is negative and `false` if the number
/// is zero or positive.
#[stable]
fn is_negative(self) -> bool;
}
macro_rules! signed_int_impl {
($T:ty) => {
#[stable]
impl SignedInt for $T {
#[inline]
fn abs(self) -> $T {
@ -651,9 +677,10 @@ signed_int_impl! { i64 }
signed_int_impl! { int }
/// A built-in unsigned integer.
#[unstable = "recently settled as part of numerics reform"]
#[stable]
pub trait UnsignedInt: Int {
/// Returns `true` iff `self == 2^k` for some `k`.
#[stable]
#[inline]
fn is_power_of_two(self) -> bool {
(self - Int::one()) & self == Int::zero() && !(self == Int::zero())
@ -661,6 +688,7 @@ pub trait UnsignedInt: Int {
/// Returns the smallest power of two greater than or equal to `self`.
/// Unspecified behavior on overflow.
#[stable]
#[inline]
fn next_power_of_two(self) -> Self {
let bits = size_of::<Self>() * 8;
@ -671,6 +699,7 @@ pub trait UnsignedInt: Int {
/// Returns the smallest power of two greater than or equal to `n`. If the
/// next power of two is greater than the type's maximum value, `None` is
/// returned, otherwise the power of two is wrapped in `Some`.
#[stable]
fn checked_next_power_of_two(self) -> Option<Self> {
let npot = self.next_power_of_two();
if npot >= self {
@ -681,19 +710,19 @@ pub trait UnsignedInt: Int {
}
}
#[unstable = "trait is unstable"]
#[stable]
impl UnsignedInt for uint {}
#[unstable = "trait is unstable"]
#[stable]
impl UnsignedInt for u8 {}
#[unstable = "trait is unstable"]
#[stable]
impl UnsignedInt for u16 {}
#[unstable = "trait is unstable"]
#[stable]
impl UnsignedInt for u32 {}
#[unstable = "trait is unstable"]
#[stable]
impl UnsignedInt for u64 {}
/// A generic trait for converting a value to a number.
@ -910,12 +939,12 @@ impl_to_primitive_uint! { u32 }
impl_to_primitive_uint! { u64 }
macro_rules! impl_to_primitive_float_to_float {
($SrcT:ty, $DstT:ty, $slf:expr) => (
($SrcT:ident, $DstT:ident, $slf:expr) => (
if size_of::<$SrcT>() <= size_of::<$DstT>() {
Some($slf as $DstT)
} else {
let n = $slf as f64;
let max_value: $SrcT = Float::max_value();
let max_value: $SrcT = ::$SrcT::MAX_VALUE;
if -max_value as f64 <= n && n <= max_value as f64 {
Some($slf as $DstT)
} else {
@ -926,7 +955,7 @@ macro_rules! impl_to_primitive_float_to_float {
}
macro_rules! impl_to_primitive_float {
($T:ty) => (
($T:ident) => (
impl ToPrimitive for $T {
#[inline]
fn to_int(&self) -> Option<int> { Some(*self as int) }
@ -1222,7 +1251,7 @@ pub enum FpCategory {
//
// FIXME(#8888): Several of these functions have a parameter named
// `unused_self`. Removing it requires #8888 to be fixed.
#[unstable = "recently settled as part of numerics reform"]
#[unstable = "distribution of methods between core/std is unclear"]
pub trait Float
: Copy + Clone
+ NumCast
@ -1248,6 +1277,39 @@ pub trait Float
/// Returns the `1` value.
fn one() -> Self;
// FIXME (#5527): These should be associated constants
/// Returns the number of binary digits of mantissa that this type supports.
#[deprecated = "use `std::f32::MANTISSA_DIGITS` or `std::f64::MANTISSA_DIGITS` as appropriate"]
fn mantissa_digits(unused_self: Option<Self>) -> uint;
/// Returns the number of base-10 digits of precision that this type supports.
#[deprecated = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate"]
fn digits(unused_self: Option<Self>) -> uint;
/// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
#[deprecated = "use `std::f32::EPSILON` or `std::f64::EPSILON` as appropriate"]
fn epsilon() -> Self;
/// Returns the minimum binary exponent that this type can represent.
#[deprecated = "use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` as appropriate"]
fn min_exp(unused_self: Option<Self>) -> int;
/// Returns the maximum binary exponent that this type can represent.
#[deprecated = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate"]
fn max_exp(unused_self: Option<Self>) -> int;
/// Returns the minimum base-10 exponent that this type can represent.
#[deprecated = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate"]
fn min_10_exp(unused_self: Option<Self>) -> int;
/// Returns the maximum base-10 exponent that this type can represent.
#[deprecated = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate"]
fn max_10_exp(unused_self: Option<Self>) -> int;
/// Returns the smallest finite value that this type can represent.
#[deprecated = "use `std::f32::MIN_VALUE` or `std::f64::MIN_VALUE` as appropriate"]
fn min_value() -> Self;
/// Returns the smallest normalized positive number that this type can represent.
#[deprecated = "use `std::f32::MIN_POS_VALUE` or `std::f64::MIN_POS_VALUE` as appropriate"]
fn min_pos_value(unused_self: Option<Self>) -> Self;
/// Returns the largest finite value that this type can represent.
#[deprecated = "use `std::f32::MAX_VALUE` or `std::f64::MAX_VALUE` as appropriate"]
fn max_value() -> Self;
/// Returns true if this value is NaN and false otherwise.
fn is_nan(self) -> bool;
/// Returns true if this value is positive infinity or negative infinity and
@ -1260,29 +1322,6 @@ pub trait Float
/// Returns the category that this number falls into.
fn classify(self) -> FpCategory;
// FIXME (#5527): These should be associated constants
/// Returns the number of binary digits of mantissa that this type supports.
fn mantissa_digits(unused_self: Option<Self>) -> uint;
/// Returns the number of base-10 digits of precision that this type supports.
fn digits(unused_self: Option<Self>) -> uint;
/// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
fn epsilon() -> Self;
/// Returns the minimum binary exponent that this type can represent.
fn min_exp(unused_self: Option<Self>) -> int;
/// Returns the maximum binary exponent that this type can represent.
fn max_exp(unused_self: Option<Self>) -> int;
/// Returns the minimum base-10 exponent that this type can represent.
fn min_10_exp(unused_self: Option<Self>) -> int;
/// Returns the maximum base-10 exponent that this type can represent.
fn max_10_exp(unused_self: Option<Self>) -> int;
/// Returns the smallest finite value that this type can represent.
fn min_value() -> Self;
/// Returns the smallest normalized positive number that this type can represent.
fn min_pos_value(unused_self: Option<Self>) -> Self;
/// Returns the largest finite value that this type can represent.
fn max_value() -> Self;
/// Returns the mantissa, exponent and sign as integers, respectively.
fn integer_decode(self) -> (u64, i16, i8);

View File

@ -19,12 +19,14 @@ use prelude::v1::*;
use intrinsics;
use libc::c_int;
use num::{Float, FloatMath};
use num::{Float, FpCategory};
use num::strconv;
use num::strconv::ExponentFormat::{ExpNone, ExpDec};
use num::strconv::SignificantDigits::{DigAll, DigMax, DigExact};
use num::strconv::SignFormat::SignNeg;
use core::num;
pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
pub use core::f32::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
pub use core::f32::{MAX_10_EXP, NAN, INFINITY, NEG_INFINITY};
@ -71,8 +73,120 @@ mod cmath {
}
}
#[unstable = "trait is unstable"]
impl FloatMath for f32 {
#[stable]
impl Float for f32 {
#[inline]
fn nan() -> f32 { num::Float::nan() }
#[inline]
fn infinity() -> f32 { num::Float::infinity() }
#[inline]
fn neg_infinity() -> f32 { num::Float::neg_infinity() }
#[inline]
fn zero() -> f32 { num::Float::zero() }
#[inline]
fn neg_zero() -> f32 { num::Float::neg_zero() }
#[inline]
fn one() -> f32 { num::Float::one() }
#[allow(deprecated)]
#[inline]
fn mantissa_digits(unused_self: Option<f32>) -> uint {
num::Float::mantissa_digits(unused_self)
}
#[allow(deprecated)]
#[inline]
fn digits(unused_self: Option<f32>) -> uint { num::Float::digits(unused_self) }
#[allow(deprecated)]
#[inline]
fn epsilon() -> f32 { num::Float::epsilon() }
#[allow(deprecated)]
#[inline]
fn min_exp(unused_self: Option<f32>) -> int { num::Float::min_exp(unused_self) }
#[allow(deprecated)]
#[inline]
fn max_exp(unused_self: Option<f32>) -> int { num::Float::max_exp(unused_self) }
#[allow(deprecated)]
#[inline]
fn min_10_exp(unused_self: Option<f32>) -> int { num::Float::min_10_exp(unused_self) }
#[allow(deprecated)]
#[inline]
fn max_10_exp(unused_self: Option<f32>) -> int { num::Float::max_10_exp(unused_self) }
#[allow(deprecated)]
#[inline]
fn min_value() -> f32 { num::Float::min_value() }
#[allow(deprecated)]
#[inline]
fn min_pos_value(unused_self: Option<f32>) -> f32 { num::Float::min_pos_value(unused_self) }
#[allow(deprecated)]
#[inline]
fn max_value() -> f32 { num::Float::max_value() }
#[inline]
fn is_nan(self) -> bool { num::Float::is_nan(self) }
#[inline]
fn is_infinite(self) -> bool { num::Float::is_infinite(self) }
#[inline]
fn is_finite(self) -> bool { num::Float::is_finite(self) }
#[inline]
fn is_normal(self) -> bool { num::Float::is_normal(self) }
#[inline]
fn classify(self) -> FpCategory { num::Float::classify(self) }
#[inline]
fn integer_decode(self) -> (u64, i16, i8) { num::Float::integer_decode(self) }
#[inline]
fn floor(self) -> f32 { num::Float::floor(self) }
#[inline]
fn ceil(self) -> f32 { num::Float::ceil(self) }
#[inline]
fn round(self) -> f32 { num::Float::round(self) }
#[inline]
fn trunc(self) -> f32 { num::Float::trunc(self) }
#[inline]
fn fract(self) -> f32 { num::Float::fract(self) }
#[inline]
fn abs(self) -> f32 { num::Float::abs(self) }
#[inline]
fn signum(self) -> f32 { num::Float::signum(self) }
#[inline]
fn is_positive(self) -> bool { num::Float::is_positive(self) }
#[inline]
fn is_negative(self) -> bool { num::Float::is_negative(self) }
#[inline]
fn mul_add(self, a: f32, b: f32) -> f32 { num::Float::mul_add(self, a, b) }
#[inline]
fn recip(self) -> f32 { num::Float::recip(self) }
#[inline]
fn powi(self, n: i32) -> f32 { num::Float::powi(self, n) }
#[inline]
fn powf(self, n: f32) -> f32 { num::Float::powf(self, n) }
#[inline]
fn sqrt(self) -> f32 { num::Float::sqrt(self) }
#[inline]
fn rsqrt(self) -> f32 { num::Float::rsqrt(self) }
#[inline]
fn exp(self) -> f32 { num::Float::exp(self) }
#[inline]
fn exp2(self) -> f32 { num::Float::exp(self) }
#[inline]
fn ln(self) -> f32 { num::Float::ln(self) }
#[inline]
fn log(self, base: f32) -> f32 { num::Float::log(self, base) }
#[inline]
fn log2(self) -> f32 { num::Float::log2(self) }
#[inline]
fn log10(self) -> f32 { num::Float::log10(self) }
#[inline]
fn to_degrees(self) -> f32 { num::Float::to_degrees(self) }
#[inline]
fn to_radians(self) -> f32 { num::Float::to_radians(self) }
/// Constructs a floating point number by multiplying `x` by 2 raised to the
/// power of `exp`
#[inline]
@ -639,18 +753,18 @@ mod tests {
// are supported in floating-point literals
let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
assert_eq!(FloatMath::ldexp(1f32, -123), f1);
assert_eq!(FloatMath::ldexp(1f32, -111), f2);
assert_eq!(Float::ldexp(1f32, -123), f1);
assert_eq!(Float::ldexp(1f32, -111), f2);
assert_eq!(FloatMath::ldexp(0f32, -123), 0f32);
assert_eq!(FloatMath::ldexp(-0f32, -123), -0f32);
assert_eq!(Float::ldexp(0f32, -123), 0f32);
assert_eq!(Float::ldexp(-0f32, -123), -0f32);
let inf: f32 = Float::infinity();
let neg_inf: f32 = Float::neg_infinity();
let nan: f32 = Float::nan();
assert_eq!(FloatMath::ldexp(inf, -123), inf);
assert_eq!(FloatMath::ldexp(neg_inf, -123), neg_inf);
assert!(FloatMath::ldexp(nan, -123).is_nan());
assert_eq!(Float::ldexp(inf, -123), inf);
assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
assert!(Float::ldexp(nan, -123).is_nan());
}
#[test]
@ -663,8 +777,8 @@ mod tests {
let (x2, exp2) = f2.frexp();
assert_eq!((x1, exp1), (0.5f32, -122));
assert_eq!((x2, exp2), (0.5f32, -110));
assert_eq!(FloatMath::ldexp(x1, exp1), f1);
assert_eq!(FloatMath::ldexp(x2, exp2), f2);
assert_eq!(Float::ldexp(x1, exp1), f1);
assert_eq!(Float::ldexp(x2, exp2), f2);
assert_eq!(0f32.frexp(), (0f32, 0));
assert_eq!((-0f32).frexp(), (-0f32, 0));

View File

@ -18,12 +18,14 @@ use prelude::v1::*;
use intrinsics;
use libc::c_int;
use num::{Float, FloatMath};
use num::{Float, FpCategory};
use num::strconv;
use num::strconv::ExponentFormat::{ExpNone, ExpDec};
use num::strconv::SignificantDigits::{DigAll, DigMax, DigExact};
use num::strconv::SignFormat::SignNeg;
use core::num;
pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
pub use core::f64::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
pub use core::f64::{MAX_10_EXP, NAN, INFINITY, NEG_INFINITY};
@ -79,10 +81,123 @@ mod cmath {
}
}
#[unstable = "trait is unstable"]
impl FloatMath for f64 {
/// Constructs a floating point number by multiplying `x` by 2 raised to the
/// power of `exp`
#[stable]
impl Float for f64 {
// inlined methods from `num::Float`
#[inline]
fn nan() -> f64 { num::Float::nan() }
#[inline]
fn infinity() -> f64 { num::Float::infinity() }
#[inline]
fn neg_infinity() -> f64 { num::Float::neg_infinity() }
#[inline]
fn zero() -> f64 { num::Float::zero() }
#[inline]
fn neg_zero() -> f64 { num::Float::neg_zero() }
#[inline]
fn one() -> f64 { num::Float::one() }
#[allow(deprecated)]
#[inline]
fn mantissa_digits(unused_self: Option<f64>) -> uint {
num::Float::mantissa_digits(unused_self)
}
#[allow(deprecated)]
#[inline]
fn digits(unused_self: Option<f64>) -> uint { num::Float::digits(unused_self) }
#[allow(deprecated)]
#[inline]
fn epsilon() -> f64 { num::Float::epsilon() }
#[allow(deprecated)]
#[inline]
fn min_exp(unused_self: Option<f64>) -> int { num::Float::min_exp(unused_self) }
#[allow(deprecated)]
#[inline]
fn max_exp(unused_self: Option<f64>) -> int { num::Float::max_exp(unused_self) }
#[allow(deprecated)]
#[inline]
fn min_10_exp(unused_self: Option<f64>) -> int { num::Float::min_10_exp(unused_self) }
#[allow(deprecated)]
#[inline]
fn max_10_exp(unused_self: Option<f64>) -> int { num::Float::max_10_exp(unused_self) }
#[allow(deprecated)]
#[inline]
fn min_value() -> f64 { num::Float::min_value() }
#[allow(deprecated)]
#[inline]
fn min_pos_value(unused_self: Option<f64>) -> f64 { num::Float::min_pos_value(unused_self) }
#[allow(deprecated)]
#[inline]
fn max_value() -> f64 { num::Float::max_value() }
#[inline]
fn is_nan(self) -> bool { num::Float::is_nan(self) }
#[inline]
fn is_infinite(self) -> bool { num::Float::is_infinite(self) }
#[inline]
fn is_finite(self) -> bool { num::Float::is_finite(self) }
#[inline]
fn is_normal(self) -> bool { num::Float::is_normal(self) }
#[inline]
fn classify(self) -> FpCategory { num::Float::classify(self) }
#[inline]
fn integer_decode(self) -> (u64, i16, i8) { num::Float::integer_decode(self) }
#[inline]
fn floor(self) -> f64 { num::Float::floor(self) }
#[inline]
fn ceil(self) -> f64 { num::Float::ceil(self) }
#[inline]
fn round(self) -> f64 { num::Float::round(self) }
#[inline]
fn trunc(self) -> f64 { num::Float::trunc(self) }
#[inline]
fn fract(self) -> f64 { num::Float::fract(self) }
#[inline]
fn abs(self) -> f64 { num::Float::abs(self) }
#[inline]
fn signum(self) -> f64 { num::Float::signum(self) }
#[inline]
fn is_positive(self) -> bool { num::Float::is_positive(self) }
#[inline]
fn is_negative(self) -> bool { num::Float::is_negative(self) }
#[inline]
fn mul_add(self, a: f64, b: f64) -> f64 { num::Float::mul_add(self, a, b) }
#[inline]
fn recip(self) -> f64 { num::Float::recip(self) }
#[inline]
fn powi(self, n: i32) -> f64 { num::Float::powi(self, n) }
#[inline]
fn powf(self, n: f64) -> f64 { num::Float::powf(self, n) }
#[inline]
fn sqrt(self) -> f64 { num::Float::sqrt(self) }
#[inline]
fn rsqrt(self) -> f64 { num::Float::rsqrt(self) }
#[inline]
fn exp(self) -> f64 { num::Float::exp(self) }
#[inline]
fn exp2(self) -> f64 { num::Float::exp(self) }
#[inline]
fn ln(self) -> f64 { num::Float::ln(self) }
#[inline]
fn log(self, base: f64) -> f64 { num::Float::log(self, base) }
#[inline]
fn log2(self) -> f64 { num::Float::log2(self) }
#[inline]
fn log10(self) -> f64 { num::Float::log10(self) }
#[inline]
fn to_degrees(self) -> f64 { num::Float::to_degrees(self) }
#[inline]
fn to_radians(self) -> f64 { num::Float::to_radians(self) }
#[inline]
fn ldexp(x: f64, exp: int) -> f64 {
unsafe { cmath::ldexp(x, exp as c_int) }
@ -640,18 +755,18 @@ mod tests {
// are supported in floating-point literals
let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
assert_eq!(FloatMath::ldexp(1f64, -123), f1);
assert_eq!(FloatMath::ldexp(1f64, -111), f2);
assert_eq!(Float::ldexp(1f64, -123), f1);
assert_eq!(Float::ldexp(1f64, -111), f2);
assert_eq!(FloatMath::ldexp(0f64, -123), 0f64);
assert_eq!(FloatMath::ldexp(-0f64, -123), -0f64);
assert_eq!(Float::ldexp(0f64, -123), 0f64);
assert_eq!(Float::ldexp(-0f64, -123), -0f64);
let inf: f64 = Float::infinity();
let neg_inf: f64 = Float::neg_infinity();
let nan: f64 = Float::nan();
assert_eq!(FloatMath::ldexp(inf, -123), inf);
assert_eq!(FloatMath::ldexp(neg_inf, -123), neg_inf);
assert!(FloatMath::ldexp(nan, -123).is_nan());
assert_eq!(Float::ldexp(inf, -123), inf);
assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
assert!(Float::ldexp(nan, -123).is_nan());
}
#[test]
@ -664,8 +779,8 @@ mod tests {
let (x2, exp2) = f2.frexp();
assert_eq!((x1, exp1), (0.5f64, -122));
assert_eq!((x2, exp2), (0.5f64, -110));
assert_eq!(FloatMath::ldexp(x1, exp1), f1);
assert_eq!(FloatMath::ldexp(x2, exp2), f2);
assert_eq!(Float::ldexp(x1, exp1), f1);
assert_eq!(Float::ldexp(x2, exp2), f2);
assert_eq!(0f64.frexp(), (0f64, 0));
assert_eq!((-0f64).frexp(), (-0f64, 0));

View File

@ -16,10 +16,12 @@
#![stable]
#![allow(missing_docs)]
#[cfg(test)] use cmp::PartialEq;
#[cfg(test)] use fmt::Show;
#[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
#[cfg(test)] use kinds::Copy;
use ops::{Add, Sub, Mul, Div, Rem, Neg};
use kinds::Copy;
use clone::Clone;
use cmp::{PartialOrd, PartialEq};
pub use core::num::{Int, SignedInt, UnsignedInt};
pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive};
@ -27,16 +29,195 @@ pub use core::num::{from_int, from_i8, from_i16, from_i32, from_i64};
pub use core::num::{from_uint, from_u8, from_u16, from_u32, from_u64};
pub use core::num::{from_f32, from_f64};
pub use core::num::{FromStrRadix, from_str_radix};
pub use core::num::{FpCategory, Float};
pub use core::num::{FpCategory};
use option::Option;
#[experimental = "may be removed or relocated"]
pub mod strconv;
/// Mathematical operations on primitive floating point numbers.
#[unstable = "may be altered to inline the Float trait"]
pub trait FloatMath: Float {
#[stable]
pub trait Float
: Copy + Clone
+ NumCast
+ PartialOrd
+ PartialEq
+ Neg<Output=Self>
+ Add<Output=Self>
+ Sub<Output=Self>
+ Mul<Output=Self>
+ Div<Output=Self>
+ Rem<Output=Self>
{
// inlined methods from `num::Float`
/// Returns the NaN value.
#[unstable = "unsure about its place in the world"]
fn nan() -> Self;
/// Returns the infinite value.
#[unstable = "unsure about its place in the world"]
fn infinity() -> Self;
/// Returns the negative infinite value.
#[unstable = "unsure about its place in the world"]
fn neg_infinity() -> Self;
/// Returns the `0` value.
#[unstable = "unsure about its place in the world"]
fn zero() -> Self;
/// Returns -0.0.
#[unstable = "unsure about its place in the world"]
fn neg_zero() -> Self;
/// Returns the `1` value.
#[unstable = "unsure about its place in the world"]
fn one() -> Self;
// FIXME (#5527): These should be associated constants
/// Returns the number of binary digits of mantissa that this type supports.
#[deprecated = "use `std::f32::MANTISSA_DIGITS` or `std::f64::MANTISSA_DIGITS` as appropriate"]
fn mantissa_digits(unused_self: Option<Self>) -> uint;
/// Returns the number of base-10 digits of precision that this type supports.
#[deprecated = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate"]
fn digits(unused_self: Option<Self>) -> uint;
/// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
#[deprecated = "use `std::f32::EPSILON` or `std::f64::EPSILON` as appropriate"]
fn epsilon() -> Self;
/// Returns the minimum binary exponent that this type can represent.
#[deprecated = "use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` as appropriate"]
fn min_exp(unused_self: Option<Self>) -> int;
/// Returns the maximum binary exponent that this type can represent.
#[deprecated = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate"]
fn max_exp(unused_self: Option<Self>) -> int;
/// Returns the minimum base-10 exponent that this type can represent.
#[deprecated = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate"]
fn min_10_exp(unused_self: Option<Self>) -> int;
/// Returns the maximum base-10 exponent that this type can represent.
#[deprecated = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate"]
fn max_10_exp(unused_self: Option<Self>) -> int;
/// Returns the smallest finite value that this type can represent.
#[unstable = "unsure about its place in the world"]
fn min_value() -> Self;
/// Returns the smallest normalized positive number that this type can represent.
#[unstable = "unsure about its place in the world"]
fn min_pos_value(unused_self: Option<Self>) -> Self;
/// Returns the largest finite value that this type can represent.
#[unstable = "unsure about its place in the world"]
fn max_value() -> Self;
/// Returns true if this value is NaN and false otherwise.
#[unstable = "position is undecided"]
fn is_nan(self) -> bool;
/// Returns true if this value is positive infinity or negative infinity and
/// false otherwise.
#[unstable = "position is undecided"]
fn is_infinite(self) -> bool;
/// Returns true if this number is neither infinite nor NaN.
#[unstable = "position is undecided"]
fn is_finite(self) -> bool;
/// Returns true if this number is neither zero, infinite, denormal, or NaN.
#[unstable = "position is undecided"]
fn is_normal(self) -> bool;
/// Returns the category that this number falls into.
#[stable]
fn classify(self) -> FpCategory;
/// Returns the mantissa, exponent and sign as integers, respectively.
#[unstable = "signature is undecided"]
fn integer_decode(self) -> (u64, i16, i8);
/// Return the largest integer less than or equal to a number.
#[stable]
fn floor(self) -> Self;
/// Return the smallest integer greater than or equal to a number.
#[stable]
fn ceil(self) -> Self;
/// Return the nearest integer to a number. Round half-way cases away from
/// `0.0`.
#[stable]
fn round(self) -> Self;
/// Return the integer part of a number.
#[stable]
fn trunc(self) -> Self;
/// Return the fractional part of a number.
#[stable]
fn fract(self) -> Self;
/// Computes the absolute value of `self`. Returns `Float::nan()` if the
/// number is `Float::nan()`.
#[stable]
fn abs(self) -> Self;
/// Returns a number that represents the sign of `self`.
///
/// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
/// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
/// - `Float::nan()` if the number is `Float::nan()`
#[stable]
fn signum(self) -> Self;
/// Returns `true` if `self` is positive, including `+0.0` and
/// `Float::infinity()`.
#[stable]
fn is_positive(self) -> bool;
/// Returns `true` if `self` is negative, including `-0.0` and
/// `Float::neg_infinity()`.
#[stable]
fn is_negative(self) -> bool;
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
/// error. This produces a more accurate result with better performance than
/// a separate multiplication operation followed by an add.
#[unstable = "unsure about its place in the world"]
fn mul_add(self, a: Self, b: Self) -> Self;
/// Take the reciprocal (inverse) of a number, `1/x`.
#[unstable = "unsure about its place in the world"]
fn recip(self) -> Self;
/// Raise a number to an integer power.
///
/// Using this function is generally faster than using `powf`
#[stable]
fn powi(self, n: i32) -> Self;
/// Raise a number to a floating point power.
#[stable]
fn powf(self, n: Self) -> Self;
/// Take the square root of a number.
///
/// Returns NaN if `self` is a negative number.
#[stable]
fn sqrt(self) -> Self;
/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
#[unstable = "unsure about its place in the world"]
fn rsqrt(self) -> Self;
/// Returns `e^(self)`, (the exponential function).
#[stable]
fn exp(self) -> Self;
/// Returns 2 raised to the power of the number, `2^(self)`.
#[stable]
fn exp2(self) -> Self;
/// Returns the natural logarithm of the number.
#[stable]
fn ln(self) -> Self;
/// Returns the logarithm of the number with respect to an arbitrary base.
#[stable]
fn log(self, base: Self) -> Self;
/// Returns the base 2 logarithm of the number.
#[stable]
fn log2(self) -> Self;
/// Returns the base 10 logarithm of the number.
#[stable]
fn log10(self) -> Self;
/// Convert radians to degrees.
#[unstable = "desirability is unclear"]
fn to_degrees(self) -> Self;
/// Convert degrees to radians.
#[unstable = "desirability is unclear"]
fn to_radians(self) -> Self;
/// Constructs a floating point number created by multiplying `x` by 2
/// raised to the power of `exp`.
#[unstable = "pending integer conventions"]
fn ldexp(x: Self, exp: int) -> Self;
/// Breaks the number into a normalized fraction and a base-2 exponent,
/// satisfying:
@ -44,76 +225,97 @@ pub trait FloatMath: Float {
/// * `self = x * pow(2, exp)`
///
/// * `0.5 <= abs(x) < 1.0`
#[unstable = "pending integer conventions"]
fn frexp(self) -> (Self, int);
/// Returns the next representable floating-point value in the direction of
/// `other`.
#[unstable = "unsure about its place in the world"]
fn next_after(self, other: Self) -> Self;
/// Returns the maximum of the two numbers.
#[stable]
fn max(self, other: Self) -> Self;
/// Returns the minimum of the two numbers.
#[stable]
fn min(self, other: Self) -> Self;
/// The positive difference of two numbers. Returns `0.0` if the number is
/// less than or equal to `other`, otherwise the difference between`self`
/// and `other` is returned.
#[unstable = "may be renamed"]
fn abs_sub(self, other: Self) -> Self;
/// Take the cubic root of a number.
#[unstable = "may be renamed"]
fn cbrt(self) -> Self;
/// Calculate the length of the hypotenuse of a right-angle triangle given
/// legs of length `x` and `y`.
#[unstable = "unsure about its place in the world"]
fn hypot(self, other: Self) -> Self;
/// Computes the sine of a number (in radians).
#[stable]
fn sin(self) -> Self;
/// Computes the cosine of a number (in radians).
#[stable]
fn cos(self) -> Self;
/// Computes the tangent of a number (in radians).
#[stable]
fn tan(self) -> Self;
/// Computes the arcsine of a number. Return value is in radians in
/// the range [-pi/2, pi/2] or NaN if the number is outside the range
/// [-1, 1].
#[stable]
fn asin(self) -> Self;
/// Computes the arccosine of a number. Return value is in radians in
/// the range [0, pi] or NaN if the number is outside the range
/// [-1, 1].
#[stable]
fn acos(self) -> Self;
/// Computes the arctangent of a number. Return value is in radians in the
/// range [-pi/2, pi/2];
#[stable]
fn atan(self) -> Self;
/// Computes the four quadrant arctangent of a number, `y`, and another
/// number `x`. Return value is in radians in the range [-pi, pi].
#[stable]
fn atan2(self, other: Self) -> Self;
/// Simultaneously computes the sine and cosine of the number, `x`. Returns
/// `(sin(x), cos(x))`.
#[stable]
fn sin_cos(self) -> (Self, Self);
/// Returns the exponential of the number, minus 1, in a way that is
/// accurate even if the number is close to zero.
#[unstable = "may be renamed"]
fn exp_m1(self) -> Self;
/// Returns the natural logarithm of the number plus 1 (`ln(1+n)`) more
/// accurately than if the operations were performed separately.
#[unstable = "may be renamed"]
fn ln_1p(self) -> Self;
/// Hyperbolic sine function.
#[stable]
fn sinh(self) -> Self;
/// Hyperbolic cosine function.
#[stable]
fn cosh(self) -> Self;
/// Hyperbolic tangent function.
#[stable]
fn tanh(self) -> Self;
/// Inverse hyperbolic sine function.
#[stable]
fn asinh(self) -> Self;
/// Inverse hyperbolic cosine function.
#[stable]
fn acosh(self) -> Self;
/// Inverse hyperbolic tangent function.
#[stable]
fn atanh(self) -> Self;
}
// DEPRECATED
/// Helper function for testing numeric operations
#[cfg(test)]
pub fn test_num<T>(ten: T, two: T) where

View File

@ -14,8 +14,6 @@
macro_rules! uint_module { ($T:ty) => (
// String conversion functions and impl num -> str
#[cfg(test)]
mod tests {
use prelude::v1::*;

View File

@ -69,7 +69,7 @@ use std::io::stdio::StdWriter;
use std::io::{File, ChanReader, ChanWriter};
use std::io;
use std::iter::repeat;
use std::num::{Float, FloatMath, Int};
use std::num::{Float, Int};
use std::os;
use std::str::FromStr;
use std::sync::mpsc::{channel, Sender};

View File

@ -17,7 +17,7 @@ use std::fmt::Show;
use std::hash::Hash;
use std::io;
use std::mem;
use std::num::{Float, FloatMath, FromPrimitive};
use std::num::{Float, FromPrimitive};
fn local_cmp<T:Float>(x: T, y: T) -> Ordering {
// arbitrarily decide that NaNs are larger than everything.
@ -39,7 +39,7 @@ fn local_sort<T: Float>(v: &mut [T]) {
}
/// Trait that provides simple descriptive statistics on a univariate set of numeric samples.
pub trait Stats <T: FloatMath + FromPrimitive> {
pub trait Stats <T: Float + FromPrimitive> {
/// Sum of the samples.
///
@ -144,7 +144,7 @@ pub struct Summary<T> {
pub iqr: T,
}
impl<T: FloatMath + FromPrimitive> Summary<T> {
impl<T: Float + FromPrimitive> Summary<T> {
/// Construct a new summary of a sample set.
pub fn new(samples: &[T]) -> Summary<T> {
Summary {
@ -164,7 +164,7 @@ impl<T: FloatMath + FromPrimitive> Summary<T> {
}
}
impl<T: FloatMath + FromPrimitive> Stats<T> for [T] {
impl<T: Float + FromPrimitive> Stats<T> for [T] {
// FIXME #11059 handle NaN, inf and overflow
fn sum(&self) -> T {
let mut partials = vec![];

View File

@ -13,7 +13,7 @@
// ignore-lexer-test FIXME #15679
use std::f32::consts::PI;
use std::num::{Float, FloatMath};
use std::num::Float;
use std::rand::{Rng, StdRng};
struct Vec2 {