From 50db7ce906b9731a5dc02a1a87fbe87f55f13b42 Mon Sep 17 00:00:00 2001 From: Stefan Plantikow Date: Wed, 14 Dec 2011 02:52:02 +0100 Subject: [PATCH] Moved std::math to std::core - merges math and float into core::float - Splits core::ctypes into core::ctypes and core::mtypes - cmath is not exported - stdtest::math passes --- src/libcore/cmath.rs | 82 +++++++++ src/libcore/core.rc | 9 +- src/libcore/ctypes.rs | 30 --- src/libcore/f32.rs | 125 +++++++++++++ src/libcore/f64.rs | 125 +++++++++++++ src/libcore/float.rs | 387 +++++++++++++++++++++++++++++++++++++++ src/libcore/mtypes.rs | 62 +++++++ src/test/stdtest/math.rs | 2 +- 8 files changed, 789 insertions(+), 33 deletions(-) create mode 100644 src/libcore/cmath.rs create mode 100644 src/libcore/f32.rs create mode 100644 src/libcore/f64.rs create mode 100644 src/libcore/mtypes.rs diff --git a/src/libcore/cmath.rs b/src/libcore/cmath.rs new file mode 100644 index 00000000000..f0fc6f87dc5 --- /dev/null +++ b/src/libcore/cmath.rs @@ -0,0 +1,82 @@ +import ctypes::c_int; + +#[link_name = "m"] +#[abi = "cdecl"] +native mod f64 { + + // Alpabetically sorted by link_name + + pure fn acos(n: f64) -> f64; + pure fn asin(n: f64) -> f64; + pure fn atan(n: f64) -> f64; + pure fn atan2(a: f64, b: f64) -> f64; + pure fn ceil(n: f64) -> f64; + pure fn cos(n: f64) -> f64; + pure fn cosh(n: f64) -> f64; + pure fn exp(n: f64) -> f64; + #[link_name="fabs"] pure fn abs(n: f64) -> f64; + pure fn floor(n: f64) -> f64; + pure fn fmod(x: f64, y: f64) -> f64; + pure fn frexp(n: f64, &value: c_int) -> f64; + pure fn ldexp(x: f64, n: c_int) -> f64; + #[link_name="log"] pure fn ln(n: f64) -> f64; + #[link_name="log1p"] pure fn ln1p(n: f64) -> f64; + pure fn log10(n: f64) -> f64; + pure fn log2(n: f64) -> f64; + pure fn modf(n: f64, iptr: *f64) -> f64; + pure fn pow(n: f64, e: f64) -> f64; + pure fn rint(n: f64) -> f64; + pure fn round(n: f64) -> f64; + pure fn sin(n: f64) -> f64; + pure fn sinh(n: f64) -> f64; + pure fn sqrt(n: f64) -> f64; + pure fn tan(n: f64) -> f64; + pure fn tanh(n: f64) -> f64; + pure fn trunc(n: f64) -> f64; +} + +#[link_name = "m"] +#[abi = "cdecl"] +native mod f32 { + + // Alpabetically sorted by link_name + + #[link_name="acosf"] pure fn acos(n: f32) -> f32; + #[link_name="asinf"] pure fn asin(n: f32) -> f32; + #[link_name="atanf"] pure fn atan(n: f32) -> f32; + #[link_name="atan2f"] pure fn atan2(a: f32, b: f32) -> f32; + #[link_name="ceilf"] pure fn ceil(n: f32) -> f32; + #[link_name="cosf"] pure fn cos(n: f32) -> f32; + #[link_name="coshf"] pure fn cosh(n: f32) -> f32; + #[link_name="expf"] pure fn exp(n: f32) -> f32; + #[link_name="fabsf"] pure fn abs(n: f32) -> f32; + #[link_name="floorf"] pure fn floor(n: f32) -> f32; + #[link_name="frexpf"] pure fn frexp(n: f64, &value: c_int) -> f32; + #[link_name="fmodf"] pure fn fmod(x: f32, y: f32) -> f32; + #[link_name="ldexpf"] pure fn ldexp(x: f32, n: c_int) -> f32; + #[link_name="logf"] pure fn ln(n: f32) -> f32; + #[link_name="log1p"] pure fn ln1p(n: f64) -> f64; + #[link_name="log2f"] pure fn log2(n: f32) -> f32; + #[link_name="log10f"] pure fn log10(n: f32) -> f32; + #[link_name="modff"] pure fn modf(n: f32, iptr: *f32) -> f32; + #[link_name="powf"] pure fn pow(n: f32, e: f32) -> f32; + #[link_name="rintf"] pure fn rint(n: f32) -> f32; + #[link_name="roundf"] pure fn round(n: f32) -> f32; + #[link_name="sinf"] pure fn sin(n: f32) -> f32; + #[link_name="sinhf"] pure fn sinh(n: f32) -> f32; + #[link_name="sqrtf"] pure fn sqrt(n: f32) -> f32; + #[link_name="tanf"] pure fn tan(n: f32) -> f32; + #[link_name="tanhf"] pure fn tanh(n: f32) -> f32; + #[link_name="truncf"] pure fn trunc(n: f32) -> f32; +} + +// +// Local Variables: +// mode: rust +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// End: +// + diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 6805c5b30c7..e35b2c0397e 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -7,9 +7,10 @@ #[license = "BSD"]; #[crate_type = "lib"]; -export box, char, float, int, str, ptr, uint, u8, u32, u64, vec, bool; +export box, char, float, f32, f64, int, str, ptr; +export uint, u8, u32, u64, vec, bool; export either, option, result; -export ctypes, sys, unsafe, comm, task; +export ctypes, mtypes, sys, unsafe, comm, task; export extfmt; // Built-in-type support modules @@ -17,6 +18,8 @@ export extfmt; mod box; mod char; mod float; +mod f32; +mod f64; mod int; mod str; mod ptr; @@ -38,6 +41,8 @@ mod result; // Runtime and language-primitive support mod ctypes; +mod mtypes; +mod cmath; mod sys; mod unsafe; mod comm; diff --git a/src/libcore/ctypes.rs b/src/libcore/ctypes.rs index 509eb3ef057..def6c5f1156 100644 --- a/src/libcore/ctypes.rs +++ b/src/libcore/ctypes.rs @@ -72,36 +72,6 @@ when interoperating with C void pointers can help in documentation. */ type void = int; -// machine type equivalents of rust int, uint, float - -/* -Type: m_int - -FIXME: What C type does this represent? -*/ -#[cfg(target_arch="x86")] -type m_int = i32; -#[cfg(target_arch="x86_64")] -type m_int = i64; - -/* -Type: m_uint - -FIXME: What C type does this represent? -*/ -#[cfg(target_arch="x86")] -type m_uint = u32; -#[cfg(target_arch="x86_64")] -type m_uint = u64; - -// This *must* match with "import m_float = fXX" in std::math per arch -/* -Type: m_float - -FIXME: What C type does this represent? -*/ -type m_float = f64; - /* Type: size_t diff --git a/src/libcore/f32.rs b/src/libcore/f32.rs new file mode 100644 index 00000000000..41110fbd7f5 --- /dev/null +++ b/src/libcore/f32.rs @@ -0,0 +1,125 @@ + +/* +Module: f32 + +Floating point operations and constants for `f32` + +This exposes the same operations as `math`, just for `f32` even though +they do not show up in the docs right now! +*/ + +import cmath::f32::*; + +export + acos, asin, atan, atan2, ceil, cos, cosh, exp, abs, floor, fmod, + frexp, ldexp, ln, ln1p, log10, log2, modf, rint, round, pow, sin, + sinh, sqrt, tan, tanh, trunc, t; + +export consts; + +type t = f32; + +/* Module: consts */ +mod consts { + + /* + Const: pi + + Archimedes' constant + */ + const pi: f32 = 3.14159265358979323846264338327950288f32; + + /* + Const: frac_pi_2 + + pi/2.0 + */ + const frac_pi_2: f32 = 1.57079632679489661923132169163975144f32; + + /* + Const: frac_pi_4 + + pi/4.0 + */ + const frac_pi_4: f32 = 0.785398163397448309615660845819875721f32; + + /* + Const: frac_1_pi + + 1.0/pi + */ + const frac_1_pi: f32 = 0.318309886183790671537767526745028724f32; + + /* + Const: frac_2_pi + + 2.0/pi + */ + const frac_2_pi: f32 = 0.636619772367581343075535053490057448f32; + + /* + Const: frac_2_sqrtpi + + 2.0/sqrt(pi) + */ + const frac_2_sqrtpi: f32 = 1.12837916709551257389615890312154517f32; + + /* + Const: sqrt2 + + sqrt(2.0) + */ + const sqrt2: f32 = 1.41421356237309504880168872420969808f32; + + /* + Const: frac_1_sqrt2 + + 1.0/sqrt(2.0) + */ + const frac_1_sqrt2: f32 = 0.707106781186547524400844362104849039f32; + + /* + Const: e + + Euler's number + */ + const e: f32 = 2.71828182845904523536028747135266250f32; + + /* + Const: log2_e + + log2(e) + */ + const log2_e: f32 = 1.44269504088896340735992468100189214f32; + + /* + Const: log10_e + + log10(e) + */ + const log10_e: f32 = 0.434294481903251827651128918916605082f32; + + /* + Const: ln_2 + + ln(2.0) + */ + const ln_2: f32 = 0.693147180559945309417232121458176568f32; + + /* + Const: ln_10 + + ln(10.0) + */ + const ln_10: f32 = 2.30258509299404568401799145468436421f32; +} + +// +// Local Variables: +// mode: rust +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// End: +// diff --git a/src/libcore/f64.rs b/src/libcore/f64.rs new file mode 100644 index 00000000000..7784933f452 --- /dev/null +++ b/src/libcore/f64.rs @@ -0,0 +1,125 @@ + +/* +Module: f64 + +Floating point operations and constants for `f64`s + +This exposes the same operations as `math`, just for `f64` even though +they do not show up in the docs right now! +*/ + +import cmath::f64::*; + +export + acos, asin, atan, atan2, ceil, cos, cosh, exp, abs, floor, fmod, + frexp, ldexp, ln, ln1p, log10, log2, modf, rint, round, pow, sin, + sinh, sqrt, tan, tanh, trunc, t; + +export consts; + +type t = f64; + +/* Module: consts */ +mod consts { + + /* + Const: pi + + Archimedes' constant + */ + const pi: f64 = 3.14159265358979323846264338327950288f64; + + /* + Const: frac_pi_2 + + pi/2.0 + */ + const frac_pi_2: f64 = 1.57079632679489661923132169163975144f64; + + /* + Const: frac_pi_4 + + pi/4.0 + */ + const frac_pi_4: f64 = 0.785398163397448309615660845819875721f64; + + /* + Const: frac_1_pi + + 1.0/pi + */ + const frac_1_pi: f64 = 0.318309886183790671537767526745028724f64; + + /* + Const: frac_2_pi + + 2.0/pi + */ + const frac_2_pi: f64 = 0.636619772367581343075535053490057448f64; + + /* + Const: frac_2_sqrtpi + + 2.0/sqrt(pi) + */ + const frac_2_sqrtpi: f64 = 1.12837916709551257389615890312154517f64; + + /* + Const: sqrt2 + + sqrt(2.0) + */ + const sqrt2: f64 = 1.41421356237309504880168872420969808f64; + + /* + Const: frac_1_sqrt2 + + 1.0/sqrt(2.0) + */ + const frac_1_sqrt2: f64 = 0.707106781186547524400844362104849039f64; + + /* + Const: e + + Euler's number + */ + const e: f64 = 2.71828182845904523536028747135266250f64; + + /* + Const: log2_e + + log2(e) + */ + const log2_e: f64 = 1.44269504088896340735992468100189214f64; + + /* + Const: log10_e + + log10(e) + */ + const log10_e: f64 = 0.434294481903251827651128918916605082f64; + + /* + Const: ln_2 + + ln(2.0) + */ + const ln_2: f64 = 0.693147180559945309417232121458176568f64; + + /* + Const: ln_10 + + ln(10.0) + */ + const ln_10: f64 = 2.30258509299404568401799145468436421f64; +} + +// +// Local Variables: +// mode: rust +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// End: +// diff --git a/src/libcore/float.rs b/src/libcore/float.rs index 015dceb1dc1..1477fdf7d80 100644 --- a/src/libcore/float.rs +++ b/src/libcore/float.rs @@ -2,6 +2,36 @@ Module: float */ +// Currently this module supports from -lm +// C95 + log2 + log1p + trunc + round + rint + +export t; + +export consts; + +export + acos, asin, atan, atan2, ceil, cos, cosh, exp, abs, floor, fmod, frexp, + ldexp, ln, ln1p, log10, log2, modf, rint, round, pow, sin, sinh, sqrt, + tan, tanh, trunc; + +export to_str_common, to_str_exact, to_str, from_str; +export lt, le, eq, ne, gt, eq; +export NaN, isNaN, infinity, neg_infinity; +export pow_uint_to_uint_as_float; +export min, max; +export add, sub, mul, div; +export positive, negative, nonpositive, nonnegative; + +import mtypes::m_float; +import ctypes::c_int; +import ptr; + +// PORT This must match in width according to architecture +import f64; +import m_float = f64; + +type t = m_float; + /** * Section: String Conversions */ @@ -332,6 +362,363 @@ pure fn nonnegative(x: float) -> bool { ret x > 0. || (1./x) == infinity; } +/* +Module: consts +*/ +mod consts { + /* + Const: pi + + Archimedes' constant + */ + const pi: float = 3.14159265358979323846264338327950288; + + /* + Const: frac_pi_2 + + pi/2.0 + */ + const frac_pi_2: float = 1.57079632679489661923132169163975144; + + /* + Const: frac_pi_4 + + pi/4.0 + */ + const frac_pi_4: float = 0.785398163397448309615660845819875721; + + /* + Const: frac_1_pi + + 1.0/pi + */ + const frac_1_pi: float = 0.318309886183790671537767526745028724; + + /* + Const: frac_2_pi + + 2.0/pi + */ + const frac_2_pi: float = 0.636619772367581343075535053490057448; + + /* + Const: frac_2_sqrtpi + + 2.0/sqrt(pi) + */ + const frac_2_sqrtpi: float = 1.12837916709551257389615890312154517; + + /* + Const: sqrt2 + + sqrt(2.0) + */ + const sqrt2: float = 1.41421356237309504880168872420969808; + + /* + Const: frac_1_sqrt2 + + 1.0/sqrt(2.0) + */ + const frac_1_sqrt2: float = 0.707106781186547524400844362104849039; + + /* + Const: e + + Euler's number + */ + const e: float = 2.71828182845904523536028747135266250; + + /* + Const: log2_e + + log2(e) + */ + const log2_e: float = 1.44269504088896340735992468100189214; + + /* + Const: log10_e + + log10(e) + */ + const log10_e: float = 0.434294481903251827651128918916605082; + + /* + Const: ln_2 + + ln(2.0) + */ + const ln_2: float = 0.693147180559945309417232121458176568; + + /* + Const: ln_10 + + ln(10.0) + */ + const ln_10: float = 2.30258509299404568401799145468436421; +} + + +// FIXME min/max type specialize via libm when overloading works +// (in theory fmax/fmin, fmaxf, fminf /should/ be faster) + +/* +Function: min + +Returns the minimum of two values +*/ +pure fn min(x: T, y: T) -> T { x < y ? x : y } + +/* +Function: max + +Returns the maximum of two values +*/ +pure fn max(x: T, y: T) -> T { x < y ? y : x } + +/* +Function: acos + +Returns the arccosine of an angle (measured in rad) +*/ +pure fn acos(x: float) -> float + { be m_float::acos(x as m_float) as float } + +/* +Function: asin + +Returns the arcsine of an angle (measured in rad) +*/ +pure fn asin(x: float) -> float + { be m_float::asin(x as m_float) as float } + +/* +Function: atan + +Returns the arctangents of an angle (measured in rad) +*/ +pure fn atan(x: float) -> float + { be m_float::atan(x as m_float) as float } + + +/* +Function: atan2 + +Returns the arctangent of an angle (measured in rad) +*/ +pure fn atan2(y: float, x: float) -> float + { be m_float::atan2(y as m_float, x as m_float) as float } + +/* +Function: ceil + +Returns the smallest integral value less than or equal to `n` +*/ +pure fn ceil(n: float) -> float + { be m_float::ceil(n as m_float) as float } + +/* +Function: cos + +Returns the cosine of an angle `x` (measured in rad) +*/ +pure fn cos(x: float) -> float + { be m_float::cos(x as m_float) as float } + +/* +Function: cosh + +Returns the hyperbolic cosine of `x` + +*/ +pure fn cosh(x: float) -> float + { be m_float::cosh(x as m_float) as float } + + +/* +Function: exp + +Returns `consts::e` to the power of `n* +*/ +pure fn exp(n: float) -> float + { be m_float::exp(n as m_float) as float } + +/* +Function: abs + +Returns the absolute value of `n` +*/ +pure fn abs(n: float) -> float + { be m_float::abs(n as m_float) as float } + +/* +Function: floor + +Returns the largest integral value less than or equal to `n` +*/ +pure fn floor(n: float) -> float + { be m_float::floor(n as m_float) as float } + +/* +Function: fmod + +Returns the floating-point remainder of `x/y` +*/ +pure fn fmod(x: float, y: float) -> float + { be m_float::fmod(x as m_float, y as m_float) as float } + +/* +Function: ln + +Returns the natural logaritm of `n` +*/ +pure fn ln(n: float) -> float + { be m_float::ln(n as m_float) as float } + +/* +Function: ldexp + +Returns `x` multiplied by 2 to the power of `n` +*/ +pure fn ldexp(n: float, i: int) -> float + { be m_float::ldexp(n as m_float, i as c_int) as float } + +/* +Function: ln1p + +Returns the natural logarithm of `1+n` accurately, +even for very small values of `n` +*/ +pure fn ln1p(n: float) -> float + { be m_float::ln1p(n as m_float) as float } + +/* +Function: log10 + +Returns the logarithm to base 10 of `n` +*/ +pure fn log10(n: float) -> float + { be m_float::log10(n as m_float) as float } + +/* +Function: log2 + +Returns the logarithm to base 2 of `n` +*/ +pure fn log2(n: float) -> float + { be m_float::log2(n as m_float) as float } + +/* +Function: modf + +Breaks `n` into integral and fractional parts such that both +have the same sign as `n` + +The integral part is stored in `iptr`. + +Returns: + +The fractional part of `n` +*/ +#[no(warn_trivial_casts)] // FIXME Implement +pure fn modf(n: float, &iptr: float) -> float { unsafe { + be m_float::modf(n as m_float, ptr::addr_of(iptr) as *m_float) as float +} } + +/* +Function: frexp + +Breaks `n` into a normalized fraction and an integral power of 2 + +The inegral part is stored in iptr. + +The functions return a number x such that x has a magnitude in the interval +[1/2, 1) or 0, and `n == x*(2 to the power of exp)`. + +Returns: + +The fractional part of `n` +*/ +pure fn frexp(n: float, &exp: c_int) -> float + { be m_float::frexp(n as m_float, exp) as float } + +/* +Function: pow +*/ +pure fn pow(v: float, e: float) -> float + { be m_float::pow(v as m_float, e as m_float) as float } + + +/* +Function: rint + +Returns the integral value nearest to `x` (according to the +prevailing rounding mode) in floating-point format +*/ +pure fn rint(x: float) -> float + { be m_float::rint(x as m_float) as float } + +/* +Function: round + + +Return the integral value nearest to `x` rounding half-way +cases away from zero, regardless of the current rounding direction. +*/ +pure fn round(x: float) -> float + { be m_float::round(x as m_float) as float } + +/* +Function: sin + +Returns the sine of an angle `x` (measured in rad) +*/ +pure fn sin(x: float) -> float + { be m_float::sin(x as m_float) as float } + +/* +Function: sinh + +Returns the hyperbolic sine of an angle `x` (measured in rad) +*/ +pure fn sinh(x: float) -> float + { be m_float::sinh(x as m_float) as float } + +/* +Function: sqrt + +Returns the square root of `x` +*/ +pure fn sqrt(x: float) -> float + { be m_float::sqrt(x as m_float) as float } + +/* +Function: tan + +Returns the tangent of an angle `x` (measured in rad) + +*/ +pure fn tan(x: float) -> float + { be m_float::tan(x as m_float) as float } + +/* +Function: tanh + +Returns the hyperbolic tangent of an angle `x` (measured in rad) + +*/ +pure fn tanh(x: float) -> float + { be m_float::tanh(x as m_float) as float } + +/* +Function: trunc + +Returns the integral value nearest to but no larger in magnitude than `x` + +*/ +pure fn trunc(x: float) -> float + { be m_float::trunc(x as m_float) as float } + // // Local Variables: // mode: rust diff --git a/src/libcore/mtypes.rs b/src/libcore/mtypes.rs new file mode 100644 index 00000000000..d4339dc091c --- /dev/null +++ b/src/libcore/mtypes.rs @@ -0,0 +1,62 @@ +/* + +Module: mtypes + +Machine type equivalents of rust int, uint, float, and complex. + +Types useful for interop with C when writing bindings that exist +for different types (float, f32, f64, ...; cf float.rs for an example) +*/ + +// PORT Change this when porting to a new architecture + +/* +Type: m_int + +Machine type equivalent of an int +*/ +#[cfg(target_arch="x86")] +type m_int = i32; +#[cfg(target_arch="x86_64")] +type m_int = i64; + +// PORT Change this when porting to a new architecture + +/* +Type: m_uint + +Machine type equivalent of a uint +*/ +#[cfg(target_arch="x86")] +type m_uint = u32; +#[cfg(target_arch="x86_64")] +type m_uint = u64; + +// PORT *must* match with "import m_float = fXX" in std::math per arch + +/* +Type: m_float + +Machine type equivalent of a float +*/ +type m_float = f64; + +// PORT *must* match "import m_complex = ..." in std::complex per arch + +/* +FIXME Type m_complex + +Machine type representing a complex value that uses floats for +both the real and the imaginary part. +*/ +// type m_complex = complex_c64::t; + +// +// Local Variables: +// mode: rust +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// End: +// diff --git a/src/test/stdtest/math.rs b/src/test/stdtest/math.rs index 9d5cf5d0c3a..cdcb581e765 100644 --- a/src/test/stdtest/math.rs +++ b/src/test/stdtest/math.rs @@ -2,7 +2,7 @@ import core::*; use std; -import std::math::*; +import float::*; import float; import c_int = ctypes::c_int;