summaryrefslogtreecommitdiff
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
parenta94679135080615136be4d83a66b3f964b8d66a4 (diff)
modulo, frexp, ldexp
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog24
-rw-r--r--bignum.c44
-rw-r--r--io.c7
-rw-r--r--math.c28
-rw-r--r--numeric.c47
-rw-r--r--version.h4
6 files changed, 137 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 1915ac4..3599a9c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+Tue Mar 17 18:23:06 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * math.c (math_frexp): newly added.
+
+ * math.c (math_ldexp): ditto.
+
+ * bignum.c (bigdivmod): calculates modulo.
+
+ * numeric.c (fix_remainder): returns reminder, formerly known as
+ modulo.
+
+ * numeric.c (fix_modulo): calculates proper `modulo'.
+
+ * bignum.c (bigdivmod): wrong sign for reminder.
+
+Mon Mar 16 17:07:28 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * experimental release 1.1b9_03.
+
+Mon Mar 16 16:33:53 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
+
+ * io.c (pipe_finalize): needed to add pipe_finalize to pipes on
+ cygwin32.
+
Mon Mar 16 14:11:06 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* class.c (ins_methods_i): needed to consider NOEX_UNDEF.
diff --git a/bignum.c b/bignum.c
index 8a6e54a..8ca00fc 100644
--- a/bignum.c
+++ b/bignum.c
@@ -662,12 +662,13 @@ big_mul(x, y)
}
static void
-bigdivmod(x, y, div, mod)
+bigdivmod(x, y, div, mod, modulo)
VALUE x, y;
VALUE *div, *mod;
+ int modulo;
{
UINT nx = RBIGNUM(x)->len, ny = RBIGNUM(y)->len, i, j;
- VALUE z;
+ VALUE yy, z;
USHORT *xds, *yds, *zds, *tds;
unsigned long t2;
long num;
@@ -703,8 +704,8 @@ bigdivmod(x, y, div, mod)
if (nx==ny) zds[nx+1] = 0;
while (!yds[ny-1]) ny--;
if ((dd = BIGRAD/(int)(yds[ny-1]+1)) != 1) {
- y = big_clone(y);
- tds = BDIGITS(y);
+ yy = big_clone(y);
+ tds = BDIGITS(yy);
j = 0;
num = 0;
while (j<ny) {
@@ -776,7 +777,16 @@ bigdivmod(x, y, div, mod)
}
}
RBIGNUM(*mod)->len = ny;
- RBIGNUM(*mod)->sign = RBIGNUM(y)->sign;
+ RBIGNUM(*mod)->sign = RBIGNUM(x)->sign;
+ if (modulo && RBIGNUM(x)->sign != RBIGNUM(y)->sign) {
+ int len = ny;
+ zds = BDIGITS(*mod);
+ while (len-- && !zds[len]);
+ if (len > 0) {
+ *mod = bigadd(*mod, y, 1);
+ return;
+ }
+ }
*mod = bignorm(*mod);
}
}
@@ -801,14 +811,16 @@ big_div(x, y)
default:
return num_coerce_bin(x, y);
}
- bigdivmod(x, y, &z, 0);
+ bigdivmod(x, y, &z, 0, 0);
return z;
}
+
static VALUE
-big_mod(x, y)
+big_modulo(x, y, modulo)
VALUE x, y;
+ int modulo;
{
VALUE z;
@@ -827,12 +839,26 @@ big_mod(x, y)
default:
return num_coerce_bin(x, y);
}
- bigdivmod(x, y, 0, &z);
+ bigdivmod(x, y, 0, &z, modulo);
return z;
}
static VALUE
+big_mod(x, y)
+ VALUE x, y;
+{
+ return big_modulo(x, y, 1);
+}
+
+static VALUE
+big_remainder(x, y)
+ VALUE x, y;
+{
+ return big_modulo(x, y, 0);
+}
+
+static VALUE
big_divmod(x, y)
VALUE x, y;
{
@@ -853,7 +879,7 @@ big_divmod(x, y)
default:
return num_coerce_bin(x, y);
}
- bigdivmod(x, y, &div, &mod);
+ bigdivmod(x, y, &div, &mod, 1);
return assoc_new(div, mod);;
}
diff --git a/io.c b/io.c
index 9f6e05b..41dac66 100644
--- a/io.c
+++ b/io.c
@@ -941,22 +941,24 @@ pipe_atexit()
}
}
-#if !defined (__CYGWIN32__)
static void
pipe_finalize(fptr)
OpenFile *fptr;
{
+#if !defined (__CYGWIN32__)
if (fptr->f != NULL) {
pclose(fptr->f);
}
if (fptr->f2 != NULL) {
pclose(fptr->f2);
}
+#else
+ fptr_finalize(fptr);
+#endif
fptr->f = fptr->f2 = NULL;
pipe_del_fptr(fptr);
}
#endif
-#endif
void
io_unbuffered(fptr)
@@ -1076,6 +1078,7 @@ pipe_open(pname, mode)
else fptr->f = f;
}
#if defined (__CYGWIN32__)
+ fptr->finalize = pipe_finalize;
pipe_add_fptr(fptr);
#endif
return (VALUE)port;
diff --git a/math.c b/math.c
index 775bdda..e531e88 100644
--- a/math.c
+++ b/math.c
@@ -90,6 +90,30 @@ math_sqrt(obj, x)
return float_new(sqrt(RFLOAT(x)->value));
}
+static VALUE
+math_frexp(obj, x)
+ VALUE obj, x;
+{
+ double d;
+ int exp;
+
+ Need_Float(x);
+ d = frexp(RFLOAT(x)->value, &exp);
+
+ return assoc_new(float_new(d), INT2NUM(exp));
+}
+
+static VALUE
+math_ldexp(obj, x, n)
+ VALUE obj, x, n;
+{
+ double d;
+ int exp;
+
+ Need_Float(x);
+ return float_new(d = ldexp(RFLOAT(x)->value, NUM2INT(n)));
+}
+
void
Init_Math()
{
@@ -115,5 +139,7 @@ Init_Math()
rb_define_module_function(mMath, "exp", math_exp, 1);
rb_define_module_function(mMath, "log", math_log, 1);
rb_define_module_function(mMath, "log10", math_log10, 1);
- rb_define_module_function(mMath, "sqrt", math_sqrt, 1);
+
+ rb_define_module_function(mMath, "frexp", math_frexp, 1);
+ rb_define_module_function(mMath, "ldexp", math_ldexp, 2);
}
diff --git a/numeric.c b/numeric.c
index 0266bbe..7ba40e6 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);
diff --git a/version.h b/version.h
index 0ae9139..0d843e3 100644
--- a/version.h
+++ b/version.h
@@ -1,2 +1,2 @@
-#define RUBY_VERSION "1.1b9_02"
-#define VERSION_DATE "98/03/13"
+#define RUBY_VERSION "1.1b9_03"
+#define VERSION_DATE "98/03/16"