[ruby-list:502] Re: bugreports(Enum#find/find_all, ruby-mode.el) and Requests
From:
matz@... (Yukihiro Matsumoto)
Date:
1996-09-11 10:12:07 UTC
List:
ruby-list #502
とりあえずパッチを流しておきます.
In message "[ruby-list:499] Re: bugreports(Enum#find/find_all, ruby-mode.el) and Requests"
on 96/09/11, Yukihiro Matsumoto <matz@caelum.co.jp> writes:
|確かに.Bignumの引き算は全般におかしいようです.これはちょっ
|と時間がかかりそうです(根が深い).
--- bignum.c~ Wed Sep 4 17:16:25 1996
+++ bignum.c Wed Sep 11 18:39:57 1996
@@ -512,13 +512,22 @@
big_minus(x, y)
VALUE x, y;
{
+ VALUE cmp;
+
if (FIXNUM_P(y)) y = int2big(FIX2INT(y));
else {
Check_Type(y, T_BIGNUM);
}
- x = bigadd(x, y, 0);
-
- return x;
+ cmp = big_cmp(x, y);
+ if (FIX2INT(cmp) == 0) {
+ return INT2FIX(0);
+ }
+ if (FIX2INT(cmp) > 0) {
+ x = bigadd(y, x, 0);
+ if (FIXNUM_P(x)) return int2inum(-FIX2INT(x));
+ return big_neg(x);
+ }
+ return bigadd(x, y, 0);
}
VALUE
@@ -1098,18 +1107,24 @@
{
struct RBignum *v;
int len;
- int i;
- len = RAND() % max->len + 1;
+ len = max->len;
v = RBIGNUM(bignew(len,1));
- for (i=0; i<v->len; i++) {
- BDIGITS(v)[i] = RAND();
+ while (len--) {
+ BDIGITS(v)[len] = RAND();
}
return big_mod(v, max);
#undef RAND
}
+static VALUE
+big_size(big)
+ struct RBignum *big;
+{
+ return INT2FIX(big->len*2);
+}
+
void
Init_Bignum()
{
@@ -1138,5 +1153,6 @@
rb_define_method(cBignum, "hash", big_hash, 0);
rb_define_method(cBignum, "to_i", big_to_i, 0);
rb_define_method(cBignum, "to_f", big_to_f, 0);
- rb_define_method(cBignum, "abs_f", big_abs, 0);
+ rb_define_method(cBignum, "abs", big_abs, 0);
+ rb_define_method(cBignum, "size", big_size, 0);
}
||>|1. Enumerable#find/find_all
||で, proc{}はない時に実行されるブロック. デフォルトの動作はnilを帰すと
||いうのはどうですか?
--- enum.c~ Wed Sep 11 01:25:31 1996
+++ enum.c Wed Sep 11 18:52:44 1996
@@ -58,26 +58,40 @@
}
}
+struct find_arg {
+ int found;
+ VALUE val;
+};
+
static void
-find_i(i, foundp)
+find_i(i, arg)
VALUE i;
- int *foundp;
+ struct find_arg *arg;
{
if (RTEST(rb_yield(i))) {
- *foundp = TRUE;
+ arg->found = TRUE;
+ arg->val = i;
rb_break();
}
}
static VALUE
-enum_find(obj)
+enum_find(argc, argv, obj)
+ int argc;
+ VALUE argv;
VALUE obj;
{
- int enum_found;
+ struct find_arg arg;
+ VALUE if_none;
- enum_found = FALSE;
- rb_iterate(rb_each, obj, find_i, &enum_found);
- return enum_found;
+ rb_scan_args(argc, argv, "01", &if_none);
+ arg.found = FALSE;
+ rb_iterate(rb_each, obj, find_i, &arg);
+ if (arg.found) {
+ return arg.val;
+ }
+ if (NIL_P(if_none)) return Qnil;
+ rb_eval_cmd(if_none, Qnil);
}
static void