summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-03-17 10:06:57 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-03-17 10:06:57 +0000
commit4c3d81d323f2876d5528fc9601cff55c88c6f566 (patch)
tree92eb620a2238c53401118b9ca5c920dbb1ca7d91 /numeric.c
parenta94679135080615136be4d83a66b3f964b8d66a4 (diff)
modulo, frexp, ldexp
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/numeric.c b/numeric.c
index 0266bbe023..7ba40e6daf 100644
--- a/numeric.c
+++ b/numeric.c
@@ -275,8 +275,9 @@ flo_div(x, y)
}
static VALUE
-flo_mod(x, y)
+flo_modulo(x, y, modulo)
VALUE x, y;
+ int modulo;
{
double value;
@@ -293,6 +294,7 @@ flo_mod(x, y)
default:
return num_coerce_bin(x, y);
}
+
#ifdef HAVE_FMOD
value = fmod(RFLOAT(x)->value, value);
#else
@@ -304,10 +306,28 @@ flo_mod(x, y)
value = value1 - value2 * value;
}
#endif
-
+ if (modulo &&
+ (RFLOAT(x)->value < 0.0) != (RFLOAT(y)->value < 0.0) &&
+ value != 0.0) {
+ value += RFLOAT(y)->value;
+ }
return float_new(value);
}
+static VALUE
+flo_mod(x, y)
+ VALUE x, y;
+{
+ return flo_modulo(x,y,1);
+}
+
+static VALUE
+flo_remainder(x, y)
+ VALUE x, y;
+{
+ return flo_modulo(x,y,0);
+}
+
VALUE
flo_pow(x, y)
VALUE x, y;
@@ -754,7 +774,7 @@ fix_div(x, y)
}
static VALUE
-fix_mod(x, y)
+fix_modulo(x, y, modulo)
VALUE x, y;
{
INT i;
@@ -763,12 +783,31 @@ fix_mod(x, y)
i = FIX2INT(y);
if (i == 0) num_zerodiv();
i = FIX2INT(x)%i;
+ if (modulo &&
+ (FIX2INT(x) < 0) != (FIX2INT(y) < 0) &&
+ i != 0) {
+ i += FIX2INT(y);
+ }
return INT2FIX(i);
}
return num_coerce_bin(x, y);
}
static VALUE
+fix_mod(x, y)
+ VALUE x, y;
+{
+ return fix_modulo(x, y, 1);
+}
+
+static VALUE
+fix_remainder(x, y)
+ VALUE x, y;
+{
+ return fix_modulo(x, y, 0);
+}
+
+static VALUE
fix_pow(x, y)
VALUE x, y;
{
@@ -1218,6 +1257,7 @@ Init_Numeric()
rb_define_method(cFixnum, "*", fix_mul, 1);
rb_define_method(cFixnum, "/", fix_div, 1);
rb_define_method(cFixnum, "%", fix_mod, 1);
+ rb_define_method(cFixnum, "remainder", fix_remainder, 1);
rb_define_method(cFixnum, "**", fix_pow, 1);
rb_define_method(cFixnum, "abs", fix_abs, 0);
@@ -1262,6 +1302,7 @@ Init_Numeric()
rb_define_method(cFloat, "*", flo_mul, 1);
rb_define_method(cFloat, "/", flo_div, 1);
rb_define_method(cFloat, "%", flo_mod, 1);
+ rb_define_method(cFloat, "remainder", flo_remainder, 1);
rb_define_method(cFloat, "**", flo_pow, 1);
rb_define_method(cFloat, "==", flo_eq, 1);
rb_define_method(cFloat, "<=>", flo_cmp, 1);