From: Takeshi NISHIMATSU Date: 2009-05-06T15:42:19+09:00 Subject: lacking in mathematical functions Do you want more mathematical functions in Ruby? I do! Here is a list of mathematical functions Ruby does not have. Please add your favorites. This issue was discussed in Japanese in [ruby-list:44246], [ruby-list:45859] and [ruby-dev:37947]. C99 has, Ruby does not: cbrt cube root function. expm1 exp(x)-1. lgamma log(|Gamma(x)|). How should we treat "extern int signgam" in ? tgamma Gamma(x) cproj project into Riemann Sphere Other special functions: Bessel functions (Gnuplot has Bessel functions.) Beta function Zeta function Bug in sqrt(Complex): Math::sqrt(Complex(-4.0,-0.0)) => (0.0+2.0i) Math::sqrt(Complex(-4.0, 0.0)) => (0.0+2.0i) It can be fixed easily with signbit or copysign. Sign (treatment of -0.0, especially): signbit test sign. Already implemented in complex.c. x.negative? and x.positive? may be a good idea. copysign copy sign of a number Here is my quick hack of copysign: --- numeric.c (revision 23350) +++ numeric.c (working copy) @@ -439,6 +439,46 @@ /* * call-seq: + * num.copysign(other) => num + * + * Copy the sign of other to num + * + */ + +static VALUE +num_copysign(VALUE x, VALUE y) +{ + double fy; + + switch (TYPE(y)) { + case T_FIXNUM: + fy = (double)FIX2LONG(y); + break; + case T_BIGNUM: + fy = rb_big2dbl(y); + break; + case T_FLOAT: + fy = RFLOAT_VALUE(y); + break; + default: + return rb_num_coerce_bin(x, y, 'copysign'); + } + + switch (TYPE(x)) { + case T_FLOAT: + return DBL2NUM(copysign(RFLOAT_VALUE(x), fy)); + break; + default: + if (copysign(1.0,fy)<0.0) { + return rb_funcall(rb_funcall(x, rb_intern("abs"), 0), rb_intern("-@"), 0); + } else { + return rb_funcall(x, rb_intern("abs"), 0); + } + } +} + +/* + * call-seq: * num.zero? => true or false * * Returns true if num has a zero value. @@ -3184,6 +3224,8 @@ rb_define_method(rb_cNumeric, "magnitude", num_abs, 0); rb_define_method(rb_cNumeric, "to_int", num_to_int, 0); + rb_define_method(rb_cNumeric, "copysign", num_copysign, 1); + rb_define_method(rb_cNumeric, "real?", num_real_p, 0); rb_define_method(rb_cNumeric, "integer?", num_int_p, 0); rb_define_method(rb_cNumeric, "zero?", num_zero_p, 0); Ciao, ciao, -- Takeshi Nishimatsu love && peace && free_software http://loto.sourceforge.net/feram/ Fast MD program for perovskite-type ferroelectrics