diff options
| author | Paolo Bosetti <[email protected]> | 2012-05-15 17:41:07 -0700 |
|---|---|---|
| committer | Paolo Bosetti <[email protected]> | 2012-05-15 17:41:07 -0700 |
| commit | 04815be9cdf3216ce925122c82d8de6db41ddded (patch) | |
| tree | 9ed740edd67f7b762b5253c7451750794c728bc9 /src/math.c | |
| parent | 9dafdfcb8ce7fafd3c2d40ab547fd30c383409b4 (diff) | |
| download | mruby-04815be9cdf3216ce925122c82d8de6db41ddded.tar.gz mruby-04815be9cdf3216ce925122c82d8de6db41ddded.zip | |
Re-added Math finctions not supported under MSVC, and added preprocessor directives to support these functions under MSVC too
Diffstat (limited to 'src/math.c')
| -rw-r--r-- | src/math.c | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/src/math.c b/src/math.c index adf02206c..2d52faaca 100644 --- a/src/math.c +++ b/src/math.c @@ -10,6 +10,39 @@ #define domain_error(msg) \ mrb_raise(mrb, E_RANGE_ERROR, "Numerical argument is out of domain - " #msg); +/* math functions not provided under Microsoft Visual C++ */ +#ifdef _MSC_VER +#define asinh(x) log(x + sqrt(pow(x,2.0) + 1)) +#define acosh(x) log(x + sqrt(pow(x,2.0) - 1)) +#define atanh(x) (log(1+x) - log(1-x))/2.0 +#define cbrt(x) pow(x,1.0/3.0) + + +double erf(double x) +{ + // constants + double a1 = 0.254829592; + double a2 = -0.284496736; + double a3 = 1.421413741; + double a4 = -1.453152027; + double a5 = 1.061405429; + double p = 0.3275911; + + // Save the sign of x + int sign = 1; + if (x < 0) + sign = -1; + x = fabs(x); + + // A&S formula 7.1.26 + double t = 1.0/(1.0 + p*x); + double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x); + + return sign*y; +} + +#endif + mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr); @@ -216,6 +249,62 @@ math_tanh(mrb_state *mrb, mrb_value obj) /* + INVERSE HYPERBOLIC TRIG FUNCTIONS +*/ + +/* + * call-seq: + * Math.asinh(x) -> float + * + * Computes the inverse hyperbolic sine of <i>x</i>. + */ +static mrb_value +math_asinh(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + + x = asinh(x); + + return mrb_float_value(x); +} + +/* + * call-seq: + * Math.acosh(x) -> float + * + * Computes the inverse hyperbolic cosine of <i>x</i>. + */ +static mrb_value +math_acosh(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = acosh(x); + + return mrb_float_value(x); +} + +/* + * call-seq: + * Math.atanh(x) -> float + * + * Computes the inverse hyperbolic tangent of <i>x</i>. + */ +static mrb_value +math_atanh(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = atanh(x); + + return mrb_float_value(x); +} + +/* EXPONENTIALS AND LOGARITHMS */ #if defined __CYGWIN__ @@ -334,6 +423,49 @@ math_log10(mrb_state *mrb, mrb_value obj) /* * call-seq: + * Math.cbrt(numeric) -> float + * + * Returns the cube root of <i>numeric</i>. + * + * -9.upto(9) {|x| + * p [x, Math.cbrt(x), Math.cbrt(x)**3] + * } + * #=> + * [-9, -2.0800838230519, -9.0] + * [-8, -2.0, -8.0] + * [-7, -1.91293118277239, -7.0] + * [-6, -1.81712059283214, -6.0] + * [-5, -1.7099759466767, -5.0] + * [-4, -1.5874010519682, -4.0] + * [-3, -1.44224957030741, -3.0] + * [-2, -1.25992104989487, -2.0] + * [-1, -1.0, -1.0] + * [0, 0.0, 0.0] + * [1, 1.0, 1.0] + * [2, 1.25992104989487, 2.0] + * [3, 1.44224957030741, 3.0] + * [4, 1.5874010519682, 4.0] + * [5, 1.7099759466767, 5.0] + * [6, 1.81712059283214, 6.0] + * [7, 1.91293118277239, 7.0] + * [8, 2.0, 8.0] + * [9, 2.0800838230519, 9.0] + * + */ +static mrb_value +math_cbrt(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = cbrt(x); + + return mrb_float_value(x); +} + + +/* + * call-seq: * Math.frexp(numeric) -> [ fraction, exponent ] * * Returns a two-element array containing the normalized fraction (a @@ -396,6 +528,43 @@ math_hypot(mrb_state *mrb, mrb_value obj) return mrb_float_value(x); } +/* + * call-seq: + * Math.erf(x) -> float + * + * Calculates the error function of x. + */ +static mrb_value +math_erf(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = erf(x); + + return mrb_float_value(x); +} + + +#ifndef _MSC_VER +/* + * call-seq: + * Math.erfc(x) -> float + * + * Calculates the complementary error function of x. + */ +static mrb_value +math_erfc(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = erfc(x); + + return mrb_float_value(x); +} +#endif + /* ------------------------------------------------------------------------*/ void mrb_init_math(mrb_state *mrb) @@ -428,13 +597,23 @@ mrb_init_math(mrb_state *mrb) mrb_define_class_method(mrb, mrb_math, "cosh", math_cosh, 1); mrb_define_class_method(mrb, mrb_math, "tanh", math_tanh, 1); + mrb_define_class_method(mrb, mrb_math, "asinh", math_asinh, 1); + mrb_define_class_method(mrb, mrb_math, "acosh", math_acosh, 1); + mrb_define_class_method(mrb, mrb_math, "atanh", math_atanh, 1); + mrb_define_class_method(mrb, mrb_math, "exp", math_exp, 1); mrb_define_class_method(mrb, mrb_math, "log", math_log, -1); mrb_define_class_method(mrb, mrb_math, "log2", math_log2, 1); mrb_define_class_method(mrb, mrb_math, "log10", math_log10, 1); + mrb_define_class_method(mrb, mrb_math, "cbrt", math_cbrt, 1); mrb_define_class_method(mrb, mrb_math, "frexp", math_frexp, 1); mrb_define_class_method(mrb, mrb_math, "ldexp", math_ldexp, 2); mrb_define_class_method(mrb, mrb_math, "hypot", math_hypot, 2); + + mrb_define_class_method(mrb, mrb_math, "erf", math_erf, 1); +#ifndef _MSC_VER + mrb_define_class_method(mrb, mrb_math, "erfc", math_erfc, 1); +#endif } |
