summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-07-06 07:21:26 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-07-06 07:21:26 +0000
commitd1375688cdde3d094984f7f3a7bffe57306a0bca (patch)
treef5320945b9bfd9fc19b133335a7be45076fe03e9 /numeric.c
parenta60db057a2a8456f8f5b59a6c5805e25d1d47d34 (diff)
matz
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@816 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c190
1 files changed, 127 insertions, 63 deletions
diff --git a/numeric.c b/numeric.c
index 01b0c0d40f..b051c4c105 100644
--- a/numeric.c
+++ b/numeric.c
@@ -133,14 +133,28 @@ num_divmod(x, y)
}
static VALUE
-num_remainder(x, y)
+num_modulo(x, y)
VALUE x, y;
{
- rb_warn("remainder is deprecated; use %% opearator");
return rb_funcall(x, '%', 1, y);
}
static VALUE
+num_remainder(x, y)
+ VALUE x, y;
+{
+ VALUE z = rb_funcall(x, '%', 1, y);
+
+ if ((RTEST(rb_funcall(x, '<', 1, INT2FIX(0))) &&
+ RTEST(rb_funcall(y, '>', 1, INT2FIX(0)))) ||
+ (RTEST(rb_funcall(x, '>', 1, INT2FIX(0))) &&
+ RTEST(rb_funcall(y, '<', 1, INT2FIX(0))))) {
+ return rb_funcall(z, '-', 1, y);
+ }
+ return z;
+}
+
+static VALUE
num_int_p(num)
VALUE num;
{
@@ -308,7 +322,7 @@ flodivmod(x, y, divp, modp)
double x, y;
double *divp, *modp;
{
- double mod;
+ double div, mod;
#ifdef HAVE_FMOD
mod = fmod(x, y);
@@ -320,10 +334,13 @@ flodivmod(x, y, divp, modp)
mod = x - z * x;
}
#endif
- if (modp) *modp = mod;
- if (divp) {
- *divp = (x - mod) / y;
+ div = (x - mod) / y;
+ if (y*mod < 0) {
+ mod += y;
+ div -= 1.0;
}
+ if (modp) *modp = mod;
+ if (divp) *divp = div;
}
static VALUE
@@ -582,19 +599,63 @@ flo_eql(x, y)
}
static VALUE
-flo_to_i(num)
+flo_to_f(num)
VALUE num;
{
- double f = RFLOAT(num)->value;
- long val;
+ return num;
+}
- if (!FIXABLE(f)) {
- return rb_dbl2big(f);
+static VALUE
+flo_abs(flt)
+ VALUE flt;
+{
+ double val = fabs(RFLOAT(flt)->value);
+ return rb_float_new(val);
+}
+
+static VALUE
+flo_zero_p(num)
+ VALUE num;
+{
+ if (RFLOAT(num)->value == 0.0) {
+ return Qtrue;
}
- val = f;
- return INT2FIX(val);
+ return Qfalse;
+}
+
+static VALUE flo_is_nan_p(num)
+ VALUE num;
+{
+
+ double value = RFLOAT(num)->value;
+
+ return isnan(value) ? Qtrue : Qfalse;
}
+static VALUE flo_is_infinite_p(num)
+ VALUE num;
+{
+ double value = RFLOAT(num)->value;
+
+ if (isinf(value)) {
+ return INT2FIX( value < 0 ? -1 : +1 );
+ }
+
+ return Qnil;
+}
+
+static VALUE flo_is_finite_p(num)
+ VALUE num;
+{
+ double value = RFLOAT(num)->value;
+
+ if (isinf(value) || isnan(value))
+ return Qfalse;
+
+ return Qtrue;
+}
+
+
static VALUE
flo_floor(num)
VALUE num;
@@ -641,64 +702,50 @@ flo_round(num)
}
static VALUE
-flo_to_f(num)
+flo_truncate(num)
VALUE num;
{
- return num;
+ double f = RFLOAT(num)->value;
+ long val;
+
+ if (f > 0.0) f = floor(f);
+ if (f < 0.0) f = ceil(f);
+
+ if (!FIXABLE(f)) {
+ return rb_dbl2big(f);
+ }
+ val = f;
+ return INT2FIX(val);
}
static VALUE
-flo_abs(flt)
- VALUE flt;
+num_floor(num)
+ VALUE num;
{
- double val = fabs(RFLOAT(flt)->value);
- return rb_float_new(val);
+ return flo_floor(rb_Float(num));
}
static VALUE
-flo_zero_p(num)
+num_ceil(num)
VALUE num;
{
- if (RFLOAT(num)->value == 0.0) {
- return Qtrue;
- }
- return Qfalse;
+ return flo_ceil(rb_Float(num));
}
-static VALUE flo_is_nan_p(num)
- VALUE num;
-{
-
- double value = RFLOAT(num)->value;
-
- return isnan(value) ? Qtrue : Qfalse;
-}
-
-static VALUE flo_is_infinite_p(num)
- VALUE num;
-{
- double value = RFLOAT(num)->value;
-
- if (isinf(value)) {
- return INT2FIX( value < 0 ? -1 : +1 );
- }
-
- return Qnil;
+static VALUE
+num_round(num)
+ VALUE num;
+{
+ return flo_round(rb_Float(num));
}
-
-static VALUE flo_is_finite_p(num)
- VALUE num;
-{
- double value = RFLOAT(num)->value;
-
- if (isinf(value) || isnan(value))
- return Qfalse;
-
- return Qtrue;
+static VALUE
+num_truncate(num)
+ VALUE num;
+{
+ return flo_truncate(rb_Float(num));
}
-
static VALUE
to_integer(val)
VALUE val;
@@ -826,6 +873,13 @@ rb_num2fix(val)
}
static VALUE
+int_to_i(num)
+ VALUE num;
+{
+ return num;
+}
+
+static VALUE
int_int_p(num)
VALUE num;
{
@@ -1017,6 +1071,10 @@ fixdivmod(x, y, divp, modp)
div = x / y;
}
mod = x - div*y;
+ if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
+ mod += y;
+ div -= 1;
+ }
if (divp) *divp = div;
if (modp) *modp = mod;
}
@@ -1266,13 +1324,6 @@ fix_aref(fix, idx)
}
static VALUE
-fix_to_i(num)
- VALUE num;
-{
- return num;
-}
-
-static VALUE
fix_to_f(num)
VALUE num;
{
@@ -1507,6 +1558,7 @@ Init_Numeric()
rb_define_method(rb_cNumeric, "===", num_equal, 1);
rb_define_method(rb_cNumeric, "eql?", num_eql, 1);
rb_define_method(rb_cNumeric, "divmod", num_divmod, 1);
+ rb_define_method(rb_cNumeric, "modulo", num_modulo, 1);
rb_define_method(rb_cNumeric, "remainder", num_remainder, 1);
rb_define_method(rb_cNumeric, "abs", num_abs, 0);
@@ -1514,6 +1566,11 @@ Init_Numeric()
rb_define_method(rb_cNumeric, "zero?", num_zero_p, 0);
rb_define_method(rb_cNumeric, "nonzero?", num_nonzero_p, 0);
+ rb_define_method(rb_cNumeric, "floor", num_floor, 0);
+ rb_define_method(rb_cNumeric, "ceil", num_ceil, 0);
+ rb_define_method(rb_cNumeric, "round", num_round, 0);
+ rb_define_method(rb_cNumeric, "truncate", num_truncate, 0);
+
rb_cInteger = rb_define_class("Integer", rb_cNumeric);
rb_define_method(rb_cInteger, "integer?", int_int_p, 0);
rb_define_method(rb_cInteger, "upto", int_upto, 1);
@@ -1524,6 +1581,11 @@ Init_Numeric()
rb_define_method(rb_cInteger, "succ", int_succ, 0);
rb_define_method(rb_cInteger, "next", int_succ, 0);
rb_define_method(rb_cInteger, "chr", int_chr, 0);
+ rb_define_method(rb_cInteger, "to_i", int_to_i, 0);
+ rb_define_method(rb_cInteger, "floor", int_to_i, 0);
+ rb_define_method(rb_cInteger, "ceil", int_to_i, 0);
+ rb_define_method(rb_cInteger, "round", int_to_i, 0);
+ rb_define_method(rb_cInteger, "truncate", int_to_i, 0);
rb_cFixnum = rb_define_class("Fixnum", rb_cInteger);
rb_include_module(rb_cFixnum, rb_mPrecision);
@@ -1543,6 +1605,7 @@ Init_Numeric()
rb_define_method(rb_cFixnum, "*", fix_mul, 1);
rb_define_method(rb_cFixnum, "/", fix_div, 1);
rb_define_method(rb_cFixnum, "%", fix_mod, 1);
+ rb_define_method(rb_cFixnum, "modulo", fix_mod, 1);
rb_define_method(rb_cFixnum, "divmod", fix_divmod, 1);
rb_define_method(rb_cFixnum, "**", fix_pow, 1);
@@ -1564,7 +1627,6 @@ Init_Numeric()
rb_define_method(rb_cFixnum, "<<", fix_lshift, 1);
rb_define_method(rb_cFixnum, ">>", fix_rshift, 1);
- rb_define_method(rb_cFixnum, "to_i", fix_to_i, 0);
rb_define_method(rb_cFixnum, "to_f", fix_to_f, 0);
rb_define_method(rb_cFixnum, "succ", fix_succ, 0);
@@ -1592,6 +1654,7 @@ Init_Numeric()
rb_define_method(rb_cFloat, "*", flo_mul, 1);
rb_define_method(rb_cFloat, "/", flo_div, 1);
rb_define_method(rb_cFloat, "%", flo_mod, 1);
+ rb_define_method(rb_cFloat, "modulo", flo_mod, 1);
rb_define_method(rb_cFloat, "divmod", flo_divmod, 1);
rb_define_method(rb_cFloat, "**", flo_pow, 1);
rb_define_method(rb_cFloat, "==", flo_eq, 1);
@@ -1602,14 +1665,15 @@ Init_Numeric()
rb_define_method(rb_cFloat, "<=", flo_le, 1);
rb_define_method(rb_cFloat, "eql?", flo_eql, 1);
rb_define_method(rb_cFloat, "hash", flo_hash, 0);
- rb_define_method(rb_cFloat, "to_i", flo_to_i, 0);
rb_define_method(rb_cFloat, "to_f", flo_to_f, 0);
rb_define_method(rb_cFloat, "abs", flo_abs, 0);
rb_define_method(rb_cFloat, "zero?", flo_zero_p, 0);
+ rb_define_method(rb_cFloat, "to_i", flo_truncate, 0);
rb_define_method(rb_cFloat, "floor", flo_floor, 0);
rb_define_method(rb_cFloat, "ceil", flo_ceil, 0);
rb_define_method(rb_cFloat, "round", flo_round, 0);
+ rb_define_method(rb_cFloat, "truncate", flo_truncate, 0);
rb_define_method(rb_cFloat, "nan?", flo_is_nan_p, 0);
rb_define_method(rb_cFloat, "infinite?", flo_is_infinite_p, 0);