fn fract(&self) -> f32 { *self - self.trunc() }
}
-impl Fractional for f32 {
+impl Real for f32 {
+ /// Archimedes' constant
+ #[inline]
+ fn pi() -> f32 { 3.14159265358979323846264338327950288 }
+
+ /// 2.0 * pi
+ #[inline]
+ fn two_pi() -> f32 { 6.28318530717958647692528676655900576 }
+
+ /// pi / 2.0
+ #[inline]
+ fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 }
+
+ /// pi / 3.0
+ #[inline]
+ fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 }
+
+ /// pi / 4.0
+ #[inline]
+ fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 }
+
+ /// pi / 6.0
+ #[inline]
+ fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 }
+
+ /// pi / 8.0
+ #[inline]
+ fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 }
+
+ /// 1 .0/ pi
+ #[inline]
+ fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 }
+
+ /// 2.0 / pi
+ #[inline]
+ fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 }
+
+ /// 2.0 / sqrt(pi)
+ #[inline]
+ fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 }
+
+ /// sqrt(2.0)
+ #[inline]
+ fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 }
+
+ /// 1.0 / sqrt(2.0)
+ #[inline]
+ fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 }
+
+ /// Euler's number
+ #[inline]
+ fn e() -> f32 { 2.71828182845904523536028747135266250 }
+
+ /// log2(e)
+ #[inline]
+ fn log2_e() -> f32 { 1.44269504088896340735992468100189214 }
+
+ /// log10(e)
+ #[inline]
+ fn log10_e() -> f32 { 0.434294481903251827651128918916605082 }
+
+ /// ln(2.0)
+ #[inline]
+ fn ln_2() -> f32 { 0.693147180559945309417232121458176568 }
+
+ /// ln(10.0)
+ #[inline]
+ fn ln_10() -> f32 { 2.30258509299404568401799145468436421 }
+
/// The reciprocal (multiplicative inverse) of the number
#[inline]
fn recip(&self) -> f32 { 1.0 / *self }
-}
-impl Algebraic for f32 {
#[inline]
fn pow(&self, n: &f32) -> f32 { pow(*self, *n) }
#[inline]
fn hypot(&self, other: &f32) -> f32 { hypot(*self, *other) }
-}
-impl Trigonometric for f32 {
#[inline]
fn sin(&self) -> f32 { sin(*self) }
fn sin_cos(&self) -> (f32, f32) {
(self.sin(), self.cos())
}
-}
-impl Exponential for f32 {
/// Returns the exponential of the number
#[inline]
fn exp(&self) -> f32 { exp(*self) }
/// Returns the base 10 logarithm of the number
#[inline]
fn log10(&self) -> f32 { log10(*self) }
-}
-impl Hyperbolic for f32 {
#[inline]
fn sinh(&self) -> f32 { sinh(*self) }
fn atanh(&self) -> f32 {
0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p()
}
-}
-
-impl Real for f32 {
- /// Archimedes' constant
- #[inline]
- fn pi() -> f32 { 3.14159265358979323846264338327950288 }
-
- /// 2.0 * pi
- #[inline]
- fn two_pi() -> f32 { 6.28318530717958647692528676655900576 }
-
- /// pi / 2.0
- #[inline]
- fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 }
-
- /// pi / 3.0
- #[inline]
- fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 }
-
- /// pi / 4.0
- #[inline]
- fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 }
-
- /// pi / 6.0
- #[inline]
- fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 }
-
- /// pi / 8.0
- #[inline]
- fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 }
-
- /// 1 .0/ pi
- #[inline]
- fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 }
-
- /// 2.0 / pi
- #[inline]
- fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 }
-
- /// 2.0 / sqrt(pi)
- #[inline]
- fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 }
-
- /// sqrt(2.0)
- #[inline]
- fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 }
-
- /// 1.0 / sqrt(2.0)
- #[inline]
- fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 }
-
- /// Euler's number
- #[inline]
- fn e() -> f32 { 2.71828182845904523536028747135266250 }
-
- /// log2(e)
- #[inline]
- fn log2_e() -> f32 { 1.44269504088896340735992468100189214 }
-
- /// log10(e)
- #[inline]
- fn log10_e() -> f32 { 0.434294481903251827651128918916605082 }
-
- /// ln(2.0)
- #[inline]
- fn ln_2() -> f32 { 0.693147180559945309417232121458176568 }
-
- /// ln(10.0)
- #[inline]
- fn ln_10() -> f32 { 2.30258509299404568401799145468436421 }
/// Converts to degrees, assuming the number is in radians
#[inline]
use default::Default;
use libc::{c_double, c_int};
use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
-use num::{Zero, One, strconv};
+use num::{Zero, One, RealExt, strconv};
use num;
use to_str;
use unstable::intrinsics;
fn fract(&self) -> f64 { *self - self.trunc() }
}
-impl Fractional for f64 {
+impl Real for f64 {
+ /// Archimedes' constant
+ #[inline]
+ fn pi() -> f64 { 3.14159265358979323846264338327950288 }
+
+ /// 2.0 * pi
+ #[inline]
+ fn two_pi() -> f64 { 6.28318530717958647692528676655900576 }
+
+ /// pi / 2.0
+ #[inline]
+ fn frac_pi_2() -> f64 { 1.57079632679489661923132169163975144 }
+
+ /// pi / 3.0
+ #[inline]
+ fn frac_pi_3() -> f64 { 1.04719755119659774615421446109316763 }
+
+ /// pi / 4.0
+ #[inline]
+ fn frac_pi_4() -> f64 { 0.785398163397448309615660845819875721 }
+
+ /// pi / 6.0
+ #[inline]
+ fn frac_pi_6() -> f64 { 0.52359877559829887307710723054658381 }
+
+ /// pi / 8.0
+ #[inline]
+ fn frac_pi_8() -> f64 { 0.39269908169872415480783042290993786 }
+
+ /// 1.0 / pi
+ #[inline]
+ fn frac_1_pi() -> f64 { 0.318309886183790671537767526745028724 }
+
+ /// 2.0 / pi
+ #[inline]
+ fn frac_2_pi() -> f64 { 0.636619772367581343075535053490057448 }
+
+ /// 2.0 / sqrt(pi)
+ #[inline]
+ fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517 }
+
+ /// sqrt(2.0)
+ #[inline]
+ fn sqrt2() -> f64 { 1.41421356237309504880168872420969808 }
+
+ /// 1.0 / sqrt(2.0)
+ #[inline]
+ fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039 }
+
+ /// Euler's number
+ #[inline]
+ fn e() -> f64 { 2.71828182845904523536028747135266250 }
+
+ /// log2(e)
+ #[inline]
+ fn log2_e() -> f64 { 1.44269504088896340735992468100189214 }
+
+ /// log10(e)
+ #[inline]
+ fn log10_e() -> f64 { 0.434294481903251827651128918916605082 }
+
+ /// ln(2.0)
+ #[inline]
+ fn ln_2() -> f64 { 0.693147180559945309417232121458176568 }
+
+ /// ln(10.0)
+ #[inline]
+ fn ln_10() -> f64 { 2.30258509299404568401799145468436421 }
+
/// The reciprocal (multiplicative inverse) of the number
#[inline]
fn recip(&self) -> f64 { 1.0 / *self }
-}
-impl Algebraic for f64 {
#[inline]
fn pow(&self, n: &f64) -> f64 { pow(*self, *n) }
#[inline]
fn hypot(&self, other: &f64) -> f64 { hypot(*self, *other) }
-}
-impl Trigonometric for f64 {
#[inline]
fn sin(&self) -> f64 { sin(*self) }
fn sin_cos(&self) -> (f64, f64) {
(self.sin(), self.cos())
}
-}
-impl Exponential for f64 {
/// Returns the exponential of the number
#[inline]
fn exp(&self) -> f64 { exp(*self) }
/// Returns the base 10 logarithm of the number
#[inline]
fn log10(&self) -> f64 { log10(*self) }
-}
-impl Hyperbolic for f64 {
#[inline]
fn sinh(&self) -> f64 { sinh(*self) }
fn atanh(&self) -> f64 {
0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p()
}
-}
-
-impl Real for f64 {
- /// Archimedes' constant
- #[inline]
- fn pi() -> f64 { 3.14159265358979323846264338327950288 }
-
- /// 2.0 * pi
- #[inline]
- fn two_pi() -> f64 { 6.28318530717958647692528676655900576 }
-
- /// pi / 2.0
- #[inline]
- fn frac_pi_2() -> f64 { 1.57079632679489661923132169163975144 }
-
- /// pi / 3.0
- #[inline]
- fn frac_pi_3() -> f64 { 1.04719755119659774615421446109316763 }
-
- /// pi / 4.0
- #[inline]
- fn frac_pi_4() -> f64 { 0.785398163397448309615660845819875721 }
-
- /// pi / 6.0
- #[inline]
- fn frac_pi_6() -> f64 { 0.52359877559829887307710723054658381 }
-
- /// pi / 8.0
- #[inline]
- fn frac_pi_8() -> f64 { 0.39269908169872415480783042290993786 }
-
- /// 1.0 / pi
- #[inline]
- fn frac_1_pi() -> f64 { 0.318309886183790671537767526745028724 }
-
- /// 2.0 / pi
- #[inline]
- fn frac_2_pi() -> f64 { 0.636619772367581343075535053490057448 }
-
- /// 2.0 / sqrt(pi)
- #[inline]
- fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517 }
-
- /// sqrt(2.0)
- #[inline]
- fn sqrt2() -> f64 { 1.41421356237309504880168872420969808 }
-
- /// 1.0 / sqrt(2.0)
- #[inline]
- fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039 }
-
- /// Euler's number
- #[inline]
- fn e() -> f64 { 2.71828182845904523536028747135266250 }
-
- /// log2(e)
- #[inline]
- fn log2_e() -> f64 { 1.44269504088896340735992468100189214 }
-
- /// log10(e)
- #[inline]
- fn log10_e() -> f64 { 0.434294481903251827651128918916605082 }
-
- /// ln(2.0)
- #[inline]
- fn ln_2() -> f64 { 0.693147180559945309417232121458176568 }
-
- /// ln(10.0)
- #[inline]
- fn ln_10() -> f64 { 2.30258509299404568401799145468436421 }
/// Converts to degrees, assuming the number is in radians
#[inline]
fn fract(&self) -> Self;
}
-/// Trait for common fractional operations.
-pub trait Fractional: Num
- + Orderable
- + Round
- + Div<Self,Self> {
+/// Defines constants and methods common to real numbers
+pub trait Real: Signed
+ + Orderable
+ + Round
+ + Div<Self,Self> {
+ // Common Constants
+ // FIXME (#5527): These should be associated constants
+ fn pi() -> Self;
+ fn two_pi() -> Self;
+ fn frac_pi_2() -> Self;
+ fn frac_pi_3() -> Self;
+ fn frac_pi_4() -> Self;
+ fn frac_pi_6() -> Self;
+ fn frac_pi_8() -> Self;
+ fn frac_1_pi() -> Self;
+ fn frac_2_pi() -> Self;
+ fn frac_2_sqrtpi() -> Self;
+ fn sqrt2() -> Self;
+ fn frac_1_sqrt2() -> Self;
+ fn e() -> Self;
+ fn log2_e() -> Self;
+ fn log10_e() -> Self;
+ fn ln_2() -> Self;
+ fn ln_10() -> Self;
+
+ // Fractional functions
+
/// Take the reciprocal (inverse) of a number, `1/x`.
fn recip(&self) -> Self;
-}
-/// A collection of algebraic operations.
-pub trait Algebraic {
+ // Algebraic functions
+
/// Raise a number to a power.
fn pow(&self, n: &Self) -> Self;
/// Take the square root of a number.
/// Calculate the length of the hypotenuse of a right-angle triangle given
/// legs of length `x` and `y`.
fn hypot(&self, other: &Self) -> Self;
-}
-/// Raise a number to a power.
-///
-/// # Example
-///
-/// ```rust
-/// use std::num;
-///
-/// let sixteen: f64 = num::pow(2.0, 4.0);
-/// assert_eq!(sixteen, 16.0);
-/// ```
-#[inline(always)] pub fn pow<T: Algebraic>(value: T, n: T) -> T { value.pow(&n) }
-/// Take the square root of a number.
-#[inline(always)] pub fn sqrt<T: Algebraic>(value: T) -> T { value.sqrt() }
-/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
-#[inline(always)] pub fn rsqrt<T: Algebraic>(value: T) -> T { value.rsqrt() }
-/// Take the cubic root of a number.
-#[inline(always)] pub fn cbrt<T: Algebraic>(value: T) -> T { value.cbrt() }
-/// Calculate the length of the hypotenuse of a right-angle triangle given legs of length `x` and
-/// `y`.
-#[inline(always)] pub fn hypot<T: Algebraic>(x: T, y: T) -> T { x.hypot(&y) }
+ // Trigonometric functions
-/// A trait for trigonometric functions.
-pub trait Trigonometric {
/// Computes the sine of a number (in radians).
fn sin(&self) -> Self;
/// Computes the cosine of a number (in radians).
/// Computes the arctangent of a number. Return value is in radians in the
/// range [-pi/2, pi/2];
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];
///
/// assert_approx_eq!((-y).atan2(&(-x)), - 2f32 * f32::consts::PI / 3f32);
/// ```
fn atan2(&self, other: &Self) -> Self;
-
/// Simultaneously computes the sine and cosine of the number, `x`. Returns
/// `(sin(x), cos(x))`.
fn sin_cos(&self) -> (Self, Self);
-}
-/// Sine function.
-#[inline(always)] pub fn sin<T: Trigonometric>(value: T) -> T { value.sin() }
-/// Cosine function.
-#[inline(always)] pub fn cos<T: Trigonometric>(value: T) -> T { value.cos() }
-/// Tangent function.
-#[inline(always)] pub fn tan<T: Trigonometric>(value: T) -> T { value.tan() }
+ // Exponential functions
-/// Compute the arcsine of the number.
-#[inline(always)] pub fn asin<T: Trigonometric>(value: T) -> T { value.asin() }
-/// Compute the arccosine of the number.
-#[inline(always)] pub fn acos<T: Trigonometric>(value: T) -> T { value.acos() }
-/// Compute the arctangent of the number.
-#[inline(always)] pub fn atan<T: Trigonometric>(value: T) -> T { value.atan() }
-
-/// Compute the arctangent with 2 arguments.
-#[inline(always)] pub fn atan2<T: Trigonometric>(x: T, y: T) -> T { x.atan2(&y) }
-/// Simultaneously computes the sine and cosine of the number.
-#[inline(always)] pub fn sin_cos<T: Trigonometric>(value: T) -> (T, T) { value.sin_cos() }
-
-/// A trait exponential functions.
-pub trait Exponential {
/// Returns `e^(self)`, (the exponential function).
fn exp(&self) -> Self;
/// Returns 2 raised to the power of the number, `2^(self)`.
fn exp2(&self) -> Self;
-
/// Returns the natural logarithm of the number.
fn ln(&self) -> Self;
/// Returns the logarithm of the number with respect to an arbitrary base.
fn log2(&self) -> Self;
/// Returns the base 10 logarithm of the number.
fn log10(&self) -> Self;
-}
-
-/// Returns `e^(value)`, (the exponential function).
-#[inline(always)] pub fn exp<T: Exponential>(value: T) -> T { value.exp() }
-/// Returns 2 raised to the power of the number, `2^(value)`.
-#[inline(always)] pub fn exp2<T: Exponential>(value: T) -> T { value.exp2() }
-/// Returns the natural logarithm of the number.
-#[inline(always)] pub fn ln<T: Exponential>(value: T) -> T { value.ln() }
-/// Returns the logarithm of the number with respect to an arbitrary base.
-#[inline(always)] pub fn log<T: Exponential>(value: T, base: T) -> T { value.log(&base) }
-/// Returns the base 2 logarithm of the number.
-#[inline(always)] pub fn log2<T: Exponential>(value: T) -> T { value.log2() }
-/// Returns the base 10 logarithm of the number.
-#[inline(always)] pub fn log10<T: Exponential>(value: T) -> T { value.log10() }
+ // Hyperbolic functions
-/// A trait hyperbolic functions.
-pub trait Hyperbolic: Exponential {
/// Hyperbolic sine function.
fn sinh(&self) -> Self;
/// Hyperbolic cosine function.
fn cosh(&self) -> Self;
/// Hyperbolic tangent function.
fn tanh(&self) -> Self;
-
/// Inverse hyperbolic sine function.
fn asinh(&self) -> Self;
/// Inverse hyperbolic cosine function.
fn acosh(&self) -> Self;
/// Inverse hyperbolic tangent function.
fn atanh(&self) -> Self;
-}
-
-/// Hyperbolic sine function.
-#[inline(always)] pub fn sinh<T: Hyperbolic>(value: T) -> T { value.sinh() }
-/// Hyperbolic cosine function.
-#[inline(always)] pub fn cosh<T: Hyperbolic>(value: T) -> T { value.cosh() }
-/// Hyperbolic tangent function.
-#[inline(always)] pub fn tanh<T: Hyperbolic>(value: T) -> T { value.tanh() }
-
-/// Inverse hyperbolic sine function.
-#[inline(always)] pub fn asinh<T: Hyperbolic>(value: T) -> T { value.asinh() }
-/// Inverse hyperbolic cosine function.
-#[inline(always)] pub fn acosh<T: Hyperbolic>(value: T) -> T { value.acosh() }
-/// Inverse hyperbolic tangent function.
-#[inline(always)] pub fn atanh<T: Hyperbolic>(value: T) -> T { value.atanh() }
-
-/// Defines constants and methods common to real numbers
-pub trait Real: Signed
- + Fractional
- + Algebraic
- + Trigonometric
- + Hyperbolic {
- // Common Constants
- // FIXME (#5527): These should be associated constants
- fn pi() -> Self;
- fn two_pi() -> Self;
- fn frac_pi_2() -> Self;
- fn frac_pi_3() -> Self;
- fn frac_pi_4() -> Self;
- fn frac_pi_6() -> Self;
- fn frac_pi_8() -> Self;
- fn frac_1_pi() -> Self;
- fn frac_2_pi() -> Self;
- fn frac_2_sqrtpi() -> Self;
- fn sqrt2() -> Self;
- fn frac_1_sqrt2() -> Self;
- fn e() -> Self;
- fn log2_e() -> Self;
- fn log10_e() -> Self;
- fn ln_2() -> Self;
- fn ln_10() -> Self;
// Angular conversions
fn to_radians(&self) -> Self;
}
+/// Raise a number to a power.
+///
+/// # Example
+///
+/// ```rust
+/// use std::num;
+///
+/// let sixteen: f64 = num::pow(2.0, 4.0);
+/// assert_eq!(sixteen, 16.0);
+/// ```
+#[inline(always)] pub fn pow<T: Real>(value: T, n: T) -> T { value.pow(&n) }
+/// Take the square root of a number.
+#[inline(always)] pub fn sqrt<T: Real>(value: T) -> T { value.sqrt() }
+/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
+#[inline(always)] pub fn rsqrt<T: Real>(value: T) -> T { value.rsqrt() }
+/// Take the cubic root of a number.
+#[inline(always)] pub fn cbrt<T: Real>(value: T) -> T { value.cbrt() }
+/// Calculate the length of the hypotenuse of a right-angle triangle given legs of length `x` and
+/// `y`.
+#[inline(always)] pub fn hypot<T: Real>(x: T, y: T) -> T { x.hypot(&y) }
+/// Sine function.
+#[inline(always)] pub fn sin<T: Real>(value: T) -> T { value.sin() }
+/// Cosine function.
+#[inline(always)] pub fn cos<T: Real>(value: T) -> T { value.cos() }
+/// Tangent function.
+#[inline(always)] pub fn tan<T: Real>(value: T) -> T { value.tan() }
+/// Compute the arcsine of the number.
+#[inline(always)] pub fn asin<T: Real>(value: T) -> T { value.asin() }
+/// Compute the arccosine of the number.
+#[inline(always)] pub fn acos<T: Real>(value: T) -> T { value.acos() }
+/// Compute the arctangent of the number.
+#[inline(always)] pub fn atan<T: Real>(value: T) -> T { value.atan() }
+/// Compute the arctangent with 2 arguments.
+#[inline(always)] pub fn atan2<T: Real>(x: T, y: T) -> T { x.atan2(&y) }
+/// Simultaneously computes the sine and cosine of the number.
+#[inline(always)] pub fn sin_cos<T: Real>(value: T) -> (T, T) { value.sin_cos() }
+/// Returns `e^(value)`, (the exponential function).
+#[inline(always)] pub fn exp<T: Real>(value: T) -> T { value.exp() }
+/// Returns 2 raised to the power of the number, `2^(value)`.
+#[inline(always)] pub fn exp2<T: Real>(value: T) -> T { value.exp2() }
+/// Returns the natural logarithm of the number.
+#[inline(always)] pub fn ln<T: Real>(value: T) -> T { value.ln() }
+/// Returns the logarithm of the number with respect to an arbitrary base.
+#[inline(always)] pub fn log<T: Real>(value: T, base: T) -> T { value.log(&base) }
+/// Returns the base 2 logarithm of the number.
+#[inline(always)] pub fn log2<T: Real>(value: T) -> T { value.log2() }
+/// Returns the base 10 logarithm of the number.
+#[inline(always)] pub fn log10<T: Real>(value: T) -> T { value.log10() }
+/// Hyperbolic sine function.
+#[inline(always)] pub fn sinh<T: Real>(value: T) -> T { value.sinh() }
+/// Hyperbolic cosine function.
+#[inline(always)] pub fn cosh<T: Real>(value: T) -> T { value.cosh() }
+/// Hyperbolic tangent function.
+#[inline(always)] pub fn tanh<T: Real>(value: T) -> T { value.tanh() }
+/// Inverse hyperbolic sine function.
+#[inline(always)] pub fn asinh<T: Real>(value: T) -> T { value.asinh() }
+/// Inverse hyperbolic cosine function.
+#[inline(always)] pub fn acosh<T: Real>(value: T) -> T { value.acosh() }
+/// Inverse hyperbolic tangent function.
+#[inline(always)] pub fn atanh<T: Real>(value: T) -> T { value.atanh() }
+
/// Methods that are harder to implement and not commonly used.
pub trait RealExt: Real {
// FIXME (#5527): usages of `int` should be replaced with an associated