auto merge of #11504 : bjz/rust/std-num-cleanups, r=brson

The gamma and bessel functions are of little utility outside a small specialized subset of use cases, and so they don't really make sense for inclusion in the standard library. The only reason they were included in the first place was to mirror libm, which is not a very good justification. If people need them for their own projects then they can make their own bindings to libm (which isn't too hard).
This commit is contained in:
bors 2014-01-12 16:16:34 -08:00
commit 6e352d7631
5 changed files with 82 additions and 237 deletions

View File

@ -979,7 +979,7 @@ impl MetricMap {
if delta.abs() <= noise {
LikelyNoise
} else {
let pct = delta.abs() / (vold.value).max(&f64::epsilon) * 100.0;
let pct = delta.abs() / (vold.value).max(&f64::EPSILON) * 100.0;
if vold.noise < 0.0 {
// When 'noise' is negative, it means we want
// to see deltas that go up over time, and can

View File

@ -9,20 +9,19 @@
// except according to those terms.
#[allow(missing_doc)];
#[allow(non_uppercase_statics)];
#[allow(dead_code)];
//! Bindings for the C math library (for basic mathematic functions)
// function names are almost identical to C's libmath, a few have been
// Function names are almost identical to C's libmath, a few have been
// renamed, grep for "rename:"
pub mod c_double_utils {
pub mod c_double {
use libc::{c_double, c_int};
#[link_name = "m"]
extern {
// Alpabetically sorted by link_name
// Alphabetically sorted by link_name
pub fn acos(n: c_double) -> c_double;
pub fn asin(n: c_double) -> c_double;
@ -79,8 +78,8 @@ pub mod c_double_utils {
pub fn ilog_radix(n: c_double) -> c_int;
pub fn modf(n: c_double, iptr: &mut c_double) -> c_double;
pub fn pow(n: c_double, e: c_double) -> c_double;
// FIXME (#1379): enable when rounding modes become available
// fn rint(n: c_double) -> c_double;
// FIXME (#1379): enable when rounding modes become available
// fn rint(n: c_double) -> c_double;
pub fn round(n: c_double) -> c_double;
// rename: for consistency with logradix
#[link_name="scalbn"]
@ -105,12 +104,12 @@ pub mod c_double_utils {
}
}
pub mod c_float_utils {
pub mod c_float {
use libc::{c_float, c_int};
#[link_name = "m"]
extern {
// Alpabetically sorted by link_name
// Alphabetically sorted by link_name
#[link_name="acosf"]
pub fn acos(n: c_float) -> c_float;
@ -185,8 +184,8 @@ pub mod c_float_utils {
pub fn modf(n: c_float, iptr: &mut c_float) -> c_float;
#[link_name="powf"]
pub fn pow(n: c_float, e: c_float) -> c_float;
// FIXME (#1379): enable when rounding modes become available
// #[link_name="rintf"] fn rint(n: c_float) -> c_float;
// FIXME (#1379): enable when rounding modes become available
// #[link_name="rintf"] fn rint(n: c_float) -> c_float;
#[link_name="roundf"]
pub fn round(n: c_float) -> c_float;
#[link_name="scalbnf"]
@ -207,101 +206,3 @@ pub mod c_float_utils {
pub fn trunc(n: c_float) -> c_float;
}
}
// PORT check these by running src/etc/machconsts.c for your architecture
// FIXME obtain machine float/math constants automatically (Issue #1986)
pub mod c_float_targ_consts {
pub static radix: uint = 2u;
pub static mantissa_digits: uint = 24u;
pub static digits: uint = 6u;
pub static min_exp: uint = -125u;
pub static max_exp: uint = 128u;
pub static min_10_exp: int = -37;
pub static max_10_exp: int = 38;
// FIXME (#1433): this is wrong, replace with hexadecimal (%a) staticants
// below.
pub static min_value: f32 = 1.175494e-38_f32;
pub static max_value: f32 = 3.402823e+38_f32;
pub static epsilon: f32 = 0.000000_f32;
}
pub mod c_double_targ_consts {
pub static radix: uint = 2u;
pub static mantissa_digits: uint = 53u;
pub static digits: uint = 15u;
pub static min_exp: uint = -1021u;
pub static max_exp: uint = 1024u;
pub static min_10_exp: int = -307;
pub static max_10_exp: int = 308;
// FIXME (#1433): this is wrong, replace with hexadecimal (%a) staticants
// below.
pub static min_value: f64 = 2.225074e-308_f64;
pub static max_value: f64 = 1.797693e+308_f64;
pub static epsilon: f64 = 2.220446e-16_f64;
}
/*
FIXME use these once they can be parsed (see Issue #1433)
pub mod c_float_math_consts {
pub static pi: c_float = 0x1.921fb6p+1_f32;
pub static div_1_pi: c_float = 0x1.45f306p-2_f32;
pub static div_2_pi: c_float = 0x1.45f306p-1_f32;
pub static div_pi_2: c_float = 0x1.921fb6p+0_f32;
pub static div_pi_4: c_float = 0x1.921fb6p-1_f32;
pub static div_2_sqrtpi: c_float = 0x1.20dd76p+0_f32;
pub static e: c_float = 0x1.5bf0a8p+1_f32;
pub static log2_e: c_float = 0x1.715476p+0_f32;
pub static log10_e: c_float = 0x1.bcb7b2p-2_f32;
pub static ln_2: c_float = 0x1.62e43p-1_f32;
pub static ln_10: c_float = 0x1.26bb1cp+1_f32;
pub static sqrt2: c_float = 0x1.6a09e6p+0_f32;
pub static div_1_sqrt2: c_float = 0x1.6a09e6p-1_f32;
}
pub mod c_double_math_consts {
pub static pi: c_double = 0x1.921fb54442d18p+1_f64;
pub static div_1_pi: c_double = 0x1.45f306dc9c883p-2_f64;
pub static div_2_pi: c_double = 0x1.45f306dc9c883p-1_f64;
pub static div_pi_2: c_double = 0x1.921fb54442d18p+0_f64;
pub static div_pi_4: c_double = 0x1.921fb54442d18p-1_f64;
pub static div_2_sqrtpi: c_double = 0x1.20dd750429b6dp+0_f64;
pub static e: c_double = 0x1.5bf0a8b145769p+1_f64;
pub static log2_e: c_double = 0x1.71547652b82fep+0_f64;
pub static log10_e: c_double = 0x1.bcb7b1526e50ep-2_f64;
pub static ln_2: c_double = 0x1.62e42fefa39efp-1_f64;
pub static ln_10: c_double = 0x1.26bb1bbb55516p+1_f64;
pub static sqrt2: c_double = 0x1.6a09e667f3bcdp+0_f64;
pub static div_1_sqrt2: c_double = 0x1.6a09e667f3bcdp-1_f64;
}
pub mod c_float_targ_consts {
pub static radix: uint = 2u;
pub static mantissa_digits: uint = 24u;
pub static digits: uint = 6u;
pub static min_exp: int = -125;
pub static max_exp: int = 128;
pub static min_10_exp: int = -37;
pub static max_10_exp: int = 38;
pub static min_value: c_float = 0x1p-126_f32;
pub static max_value: c_float = 0x1.fffffep+127_f32;
pub static epsilon: c_float = 0x1p-23_f32;
}
pub mod c_double_targ_consts {
pub static radix: uint = 2u;
pub static mantissa_digits: uint = 53u;
pub static digits: uint = 15u;
pub static min_exp: int = -1021;
pub static max_exp: int = 1024;
pub static min_10_exp: int = -307;
pub static max_10_exp: int = 308;
pub static min_value: c_double = 0x1p-1022_f64;
pub static max_value: c_double = 0x1.fffffffffffffp+1023_f64;
pub static epsilon: c_double = 0x1p-52_f64;
}
*/

View File

@ -13,7 +13,7 @@
use prelude::*;
use cmath::c_float_utils;
use cmath;
use default::Default;
use libc::{c_float, c_int};
use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
@ -22,8 +22,6 @@ use num;
use to_str;
use unstable::intrinsics;
pub use cmath::c_float_targ_consts::*;
macro_rules! delegate(
(
$(
@ -62,8 +60,8 @@ delegate!(
fn sqrt(n: f32) -> f32 = intrinsics::sqrtf32,
// LLVM 3.3 required to use intrinsics for these four
fn ceil(n: c_float) -> c_float = c_float_utils::ceil,
fn trunc(n: c_float) -> c_float = c_float_utils::trunc,
fn ceil(n: c_float) -> c_float = cmath::c_float::ceil,
fn trunc(n: c_float) -> c_float = cmath::c_float::trunc,
/*
fn ceil(n: f32) -> f32 = intrinsics::ceilf32,
fn trunc(n: f32) -> f32 = intrinsics::truncf32,
@ -72,48 +70,54 @@ delegate!(
*/
// cmath
fn acos(n: c_float) -> c_float = c_float_utils::acos,
fn asin(n: c_float) -> c_float = c_float_utils::asin,
fn atan(n: c_float) -> c_float = c_float_utils::atan,
fn atan2(a: c_float, b: c_float) -> c_float = c_float_utils::atan2,
fn cbrt(n: c_float) -> c_float = c_float_utils::cbrt,
fn copysign(x: c_float, y: c_float) -> c_float = c_float_utils::copysign,
fn cosh(n: c_float) -> c_float = c_float_utils::cosh,
// fn erf(n: c_float) -> c_float = c_float_utils::erf,
// fn erfc(n: c_float) -> c_float = c_float_utils::erfc,
fn exp_m1(n: c_float) -> c_float = c_float_utils::exp_m1,
fn abs_sub(a: c_float, b: c_float) -> c_float = c_float_utils::abs_sub,
fn next_after(x: c_float, y: c_float) -> c_float = c_float_utils::next_after,
fn frexp(n: c_float, value: &mut c_int) -> c_float = c_float_utils::frexp,
fn hypot(x: c_float, y: c_float) -> c_float = c_float_utils::hypot,
fn ldexp(x: c_float, n: c_int) -> c_float = c_float_utils::ldexp,
// fn lgamma(n: c_float, sign: &mut c_int) -> c_float = c_float_utils::lgamma,
// fn log_radix(n: c_float) -> c_float = c_float_utils::log_radix,
fn ln_1p(n: c_float) -> c_float = c_float_utils::ln_1p,
// fn ilog_radix(n: c_float) -> c_int = c_float_utils::ilog_radix,
// fn modf(n: c_float, iptr: &mut c_float) -> c_float = c_float_utils::modf,
fn round(n: c_float) -> c_float = c_float_utils::round,
// fn ldexp_radix(n: c_float, i: c_int) -> c_float = c_float_utils::ldexp_radix,
fn sinh(n: c_float) -> c_float = c_float_utils::sinh,
fn tan(n: c_float) -> c_float = c_float_utils::tan,
fn tanh(n: c_float) -> c_float = c_float_utils::tanh
// fn tgamma(n: c_float) -> c_float = c_float_utils::tgamma
fn acos(n: c_float) -> c_float = cmath::c_float::acos,
fn asin(n: c_float) -> c_float = cmath::c_float::asin,
fn atan(n: c_float) -> c_float = cmath::c_float::atan,
fn atan2(a: c_float, b: c_float) -> c_float = cmath::c_float::atan2,
fn cbrt(n: c_float) -> c_float = cmath::c_float::cbrt,
fn copysign(x: c_float, y: c_float) -> c_float = cmath::c_float::copysign,
fn cosh(n: c_float) -> c_float = cmath::c_float::cosh,
// fn erf(n: c_float) -> c_float = cmath::c_float::erf,
// fn erfc(n: c_float) -> c_float = cmath::c_float::erfc,
fn exp_m1(n: c_float) -> c_float = cmath::c_float::exp_m1,
fn abs_sub(a: c_float, b: c_float) -> c_float = cmath::c_float::abs_sub,
fn next_after(x: c_float, y: c_float) -> c_float = cmath::c_float::next_after,
fn frexp(n: c_float, value: &mut c_int) -> c_float = cmath::c_float::frexp,
fn hypot(x: c_float, y: c_float) -> c_float = cmath::c_float::hypot,
fn ldexp(x: c_float, n: c_int) -> c_float = cmath::c_float::ldexp,
// fn log_radix(n: c_float) -> c_float = cmath::c_float::log_radix,
fn ln_1p(n: c_float) -> c_float = cmath::c_float::ln_1p,
// fn ilog_radix(n: c_float) -> c_int = cmath::c_float::ilog_radix,
// fn modf(n: c_float, iptr: &mut c_float) -> c_float = cmath::c_float::modf,
fn round(n: c_float) -> c_float = cmath::c_float::round,
// fn ldexp_radix(n: c_float, i: c_int) -> c_float = cmath::c_float::ldexp_radix,
fn sinh(n: c_float) -> c_float = cmath::c_float::sinh,
fn tan(n: c_float) -> c_float = cmath::c_float::tan,
fn tanh(n: c_float) -> c_float = cmath::c_float::tanh
)
// These are not defined inside consts:: for consistency with
// the integer types
pub static RADIX: uint = 2u;
pub static MANTISSA_DIGITS: uint = 53u;
pub static DIGITS: uint = 15u;
pub static EPSILON: f64 = 2.220446e-16_f64;
// FIXME (#1433): this is wrong, replace with hexadecimal (%a) statics
// below.
pub static MIN_VALUE: f64 = 2.225074e-308_f64;
pub static MAX_VALUE: f64 = 1.797693e+308_f64;
pub static MIN_EXP: uint = -1021u;
pub static MAX_EXP: uint = 1024u;
pub static MIN_10_EXP: int = -307;
pub static MAX_10_EXP: int = 308;
pub static NAN: f32 = 0.0_f32/0.0_f32;
pub static INFINITY: f32 = 1.0_f32/0.0_f32;
pub static NEG_INFINITY: f32 = -1.0_f32/0.0_f32;
// FIXME (#1999): replace the predicates below with llvm intrinsics or
// calls to the libmath macros in the rust runtime for performance.
// FIXME (#1999): add is_normal, is_subnormal, and fpclassify.
/* Module: consts */
pub mod consts {
// FIXME (requires Issue #1433 to fix): replace with mathematical

View File

@ -14,16 +14,15 @@
use prelude::*;
use cmath::c_double_utils;
use cmath;
use default::Default;
use libc::{c_double, c_int};
use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
use num::{Zero, One, RealExt, strconv};
use num::{Zero, One, strconv};
use num;
use to_str;
use unstable::intrinsics;
pub use cmath::c_double_targ_consts::*;
pub use cmp::{min, max};
macro_rules! delegate(
@ -64,8 +63,8 @@ delegate!(
fn sqrt(n: f64) -> f64 = intrinsics::sqrtf64,
// LLVM 3.3 required to use intrinsics for these four
fn ceil(n: c_double) -> c_double = c_double_utils::ceil,
fn trunc(n: c_double) -> c_double = c_double_utils::trunc,
fn ceil(n: c_double) -> c_double = cmath::c_double::ceil,
fn trunc(n: c_double) -> c_double = cmath::c_double::trunc,
/*
fn ceil(n: f64) -> f64 = intrinsics::ceilf64,
fn trunc(n: f64) -> f64 = intrinsics::truncf64,
@ -74,45 +73,34 @@ delegate!(
*/
// cmath
fn acos(n: c_double) -> c_double = c_double_utils::acos,
fn asin(n: c_double) -> c_double = c_double_utils::asin,
fn atan(n: c_double) -> c_double = c_double_utils::atan,
fn atan2(a: c_double, b: c_double) -> c_double = c_double_utils::atan2,
fn cbrt(n: c_double) -> c_double = c_double_utils::cbrt,
fn copysign(x: c_double, y: c_double) -> c_double = c_double_utils::copysign,
fn cosh(n: c_double) -> c_double = c_double_utils::cosh,
// fn erf(n: c_double) -> c_double = c_double_utils::erf,
// fn erfc(n: c_double) -> c_double = c_double_utils::erfc,
fn exp_m1(n: c_double) -> c_double = c_double_utils::exp_m1,
fn abs_sub(a: c_double, b: c_double) -> c_double = c_double_utils::abs_sub,
fn next_after(x: c_double, y: c_double) -> c_double = c_double_utils::next_after,
fn frexp(n: c_double, value: &mut c_int) -> c_double = c_double_utils::frexp,
fn hypot(x: c_double, y: c_double) -> c_double = c_double_utils::hypot,
fn ldexp(x: c_double, n: c_int) -> c_double = c_double_utils::ldexp,
fn lgamma(n: c_double, sign: &mut c_int) -> c_double = c_double_utils::lgamma,
// fn log_radix(n: c_double) -> c_double = c_double_utils::log_radix,
fn ln_1p(n: c_double) -> c_double = c_double_utils::ln_1p,
// fn ilog_radix(n: c_double) -> c_int = c_double_utils::ilog_radix,
// fn modf(n: c_double, iptr: &mut c_double) -> c_double = c_double_utils::modf,
fn round(n: c_double) -> c_double = c_double_utils::round,
// fn ldexp_radix(n: c_double, i: c_int) -> c_double = c_double_utils::ldexp_radix,
fn sinh(n: c_double) -> c_double = c_double_utils::sinh,
fn tan(n: c_double) -> c_double = c_double_utils::tan,
fn tanh(n: c_double) -> c_double = c_double_utils::tanh,
fn tgamma(n: c_double) -> c_double = c_double_utils::tgamma,
fn j0(n: c_double) -> c_double = c_double_utils::j0,
fn j1(n: c_double) -> c_double = c_double_utils::j1,
fn jn(i: c_int, n: c_double) -> c_double = c_double_utils::jn,
fn y0(n: c_double) -> c_double = c_double_utils::y0,
fn y1(n: c_double) -> c_double = c_double_utils::y1,
fn yn(i: c_int, n: c_double) -> c_double = c_double_utils::yn
fn acos(n: c_double) -> c_double = cmath::c_double::acos,
fn asin(n: c_double) -> c_double = cmath::c_double::asin,
fn atan(n: c_double) -> c_double = cmath::c_double::atan,
fn atan2(a: c_double, b: c_double) -> c_double = cmath::c_double::atan2,
fn cbrt(n: c_double) -> c_double = cmath::c_double::cbrt,
fn copysign(x: c_double, y: c_double) -> c_double = cmath::c_double::copysign,
fn cosh(n: c_double) -> c_double = cmath::c_double::cosh,
// fn erf(n: c_double) -> c_double = cmath::c_double::erf,
// fn erfc(n: c_double) -> c_double = cmath::c_double::erfc,
fn exp_m1(n: c_double) -> c_double = cmath::c_double::exp_m1,
fn abs_sub(a: c_double, b: c_double) -> c_double = cmath::c_double::abs_sub,
fn next_after(x: c_double, y: c_double) -> c_double = cmath::c_double::next_after,
fn frexp(n: c_double, value: &mut c_int) -> c_double = cmath::c_double::frexp,
fn hypot(x: c_double, y: c_double) -> c_double = cmath::c_double::hypot,
fn ldexp(x: c_double, n: c_int) -> c_double = cmath::c_double::ldexp,
// fn log_radix(n: c_double) -> c_double = cmath::c_double::log_radix,
fn ln_1p(n: c_double) -> c_double = cmath::c_double::ln_1p,
// fn ilog_radix(n: c_double) -> c_int = cmath::c_double::ilog_radix,
// fn modf(n: c_double, iptr: &mut c_double) -> c_double = cmath::c_double::modf,
fn round(n: c_double) -> c_double = cmath::c_double::round,
// fn ldexp_radix(n: c_double, i: c_int) -> c_double = cmath::c_double::ldexp_radix,
fn sinh(n: c_double) -> c_double = cmath::c_double::sinh,
fn tan(n: c_double) -> c_double = cmath::c_double::tan,
fn tanh(n: c_double) -> c_double = cmath::c_double::tanh
)
// FIXME (#1433): obtain these in a different way
// These are not defined inside consts:: for consistency with
// the integer types
pub static RADIX: uint = 2u;
pub static MANTISSA_DIGITS: uint = 53u;
@ -560,36 +548,6 @@ impl Real for f64 {
}
}
impl RealExt for f64 {
#[inline]
fn lgamma(&self) -> (int, f64) {
let mut sign = 0;
let result = lgamma(*self, &mut sign);
(sign as int, result)
}
#[inline]
fn tgamma(&self) -> f64 { tgamma(*self) }
#[inline]
fn j0(&self) -> f64 { j0(*self) }
#[inline]
fn j1(&self) -> f64 { j1(*self) }
#[inline]
fn jn(&self, n: int) -> f64 { jn(n as c_int, *self) }
#[inline]
fn y0(&self) -> f64 { y0(*self) }
#[inline]
fn y1(&self) -> f64 { y1(*self) }
#[inline]
fn yn(&self, n: int) -> f64 { yn(n as c_int, *self) }
}
impl Bounded for f64 {
#[inline]
fn min_value() -> f64 { 2.2250738585072014e-308 }

View File

@ -324,24 +324,6 @@ pub trait Real: Signed
/// 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
// integer type once these are implemented
// Gamma functions
fn lgamma(&self) -> (int, Self);
fn tgamma(&self) -> Self;
// Bessel functions
fn j0(&self) -> Self;
fn j1(&self) -> Self;
fn jn(&self, n: int) -> Self;
fn y0(&self) -> Self;
fn y1(&self) -> Self;
fn yn(&self, n: int) -> Self;
}
/// Collects the bitwise operators under one trait.
pub trait Bitwise: Not<Self>
+ BitAnd<Self,Self>