[#31166] is_ruby_native_thread() — Masahiro Sakai (酒井政裕) <masahiro.sakai@...>

酒井です。

16 messages 2007/07/08
[#31269] Re: is_ruby_native_thread() — Nobuyoshi Nakada <nobu@...> 2007/07/21

なかだです。

[#31270] Re: is_ruby_native_thread() — Hidetoshi NAGAI <nagai@...> 2007/07/22

永井@知能.九工大です.

[#31298] retryの使い方 — eklerni <eklerni@...>

松尾といいます。

52 messages 2007/07/25
[#31299] Re: retryの使い方 — SASADA Koichi <ko1@...> 2007/07/26

 ささだです。

[#31300] Re: retryの使い方 — eklerni <eklerni@...> 2007/07/26

松尾です、返信ありがとうございます。

[#31303] Re: retryの使い方 — Yugui <yugui@...> 2007/07/26

Yuguiといいます。

[#31306] Re: retryの使い方 — eklerni <eklerni@...> 2007/07/26

松尾といいます。

[#31308] Re: retryの使い方 — Tanaka Akira <akr@...> 2007/07/26

In article <46A909DD.1070405@for.mail-box.ne.jp>,

[#31310] Re: retryの使い方 — eklerni <eklerni@...> 2007/07/26

Tanaka Akira さんは書きました:

[#31314] Re: retryの使い方 — Tanaka Akira <akr@...> 2007/07/30

In article <46A92530.80507@for.mail-box.ne.jp>,

[#31315] Re: retryの使い方 — eklerni <eklerni@...> 2007/07/30

Tanaka Akira さんは書きました:

[#31316] Re: retryの使い方 — Tanaka Akira <akr@...> 2007/07/30

In article <46AD7A16.8080509@for.mail-box.ne.jp>,

[#31317] Re: retryの使い方 — eklerni <eklerni@...> 2007/07/31

松尾です。

[#31381] Re: retryの使い方 — SASADA Koichi <ko1@...> 2007/08/12

 ささだです。

[#31422] Re: retryの使い方 — Yukihiro Matsumoto <matz@...> 2007/08/15

まつもと ゆきひろです

[#31425] Re: retryの使い方 — Tanaka Akira <akr@...> 2007/08/15

In article <E1ILDTi-0005T6-Be@x31>,

[#31426] Re: retryの使い方 — Yukihiro Matsumoto <matz@...> 2007/08/15

まつもと ゆきひろです

[#31433] Re: retryの使い方 — Tanaka Akira <akr@...> 2007/08/16

In article <E1ILKn6-0003Nv-0f@x31>,

[#31435] Re: retryの使い方 — Yukihiro Matsumoto <matz@...> 2007/08/16

まつもと ゆきひろです

[#31447] Re: retryの使い方 — Tanaka Akira <akr@...> 2007/08/16

In article <E1ILVN9-0006xJ-7I@x31>,

[#31450] Re: retryの使い方 — Tanaka Akira <akr@...> 2007/08/17

In article <E1ILq4x-0002Bs-Lg@x31>,

[#31451] Re: retryの使い方 — Yukihiro Matsumoto <matz@...> 2007/08/17

まつもと ゆきひろです

[ruby-dev:31245] Re: shift

From: Nobuyoshi Nakada <nobu@...>
Date: 2007-07-18 07:43:30 UTC
List: ruby-dev #31245
なかだです。

At Wed, 18 Jul 2007 12:42:11 +0900,
Tanaka Akira wrote in [ruby-dev:31244]:
> -O0 で、以下のようにすると SEGV になります。
(ry

こんなところでどうでしょうか。


Index: bignum.c
===================================================================
--- bignum.c	(revision 12812)
+++ bignum.c	(working copy)
@@ -1530,5 +1537,15 @@ bdigbitsize(BDIGIT x)
 }
 
-static VALUE rb_big_rshift(VALUE,VALUE);
+static VALUE big_lshift(VALUE, unsigned int);
+static VALUE big_rshift(VALUE, unsigned int);
+
+static VALUE big_shift(VALUE x, int n)
+{
+    if (n < 0)
+	return big_lshift(x, (unsigned int)n);
+    else if (n > 0)
+	return big_rshift(x, (unsigned int)n);
+    return x;
+}
 
 /*
@@ -1559,5 +1576,5 @@ rb_big_quo(VALUE x, VALUE y)
 	ex += bdigbitsize(BDIGITS(x)[RBIGNUM(x)->len - 1]);
 	ex -= 2 * DBL_BIGDIG * BITSPERDIG;
-	if (ex) x = rb_big_rshift(x, INT2FIX(ex));
+	if (ex) x = big_shift(x, ex);
 
 	switch (TYPE(y)) {
@@ -1568,5 +1585,5 @@ rb_big_quo(VALUE x, VALUE y)
 	    ey += bdigbitsize(BDIGITS(y)[RBIGNUM(y)->len - 1]);
 	    ey -= DBL_BIGDIG * BITSPERDIG;
-	    if (ey) y = rb_big_rshift(y, INT2FIX(ey));
+	    if (ey) y = big_shift(y, ey);
 	  bignum:
 	    bigdivrem(x, y, &z, 0);
@@ -1659,4 +1676,5 @@ rb_big_pow(VALUE x, VALUE y)
     double d;
     SIGNED_VALUE yy;
+    int odd = 0;
 
     if (y == INT2FIX(0)) return INT2FIX(1);
@@ -1669,4 +1687,5 @@ rb_big_pow(VALUE x, VALUE y)
 	rb_warn("in a**b, b may be too big");
 	d = rb_big2dbl(y);
+	odd = rb_big_odd_p(y);
 	break;
 
@@ -1679,4 +1698,5 @@ rb_big_pow(VALUE x, VALUE y)
 	    if (RBIGNUM(x)->len * SIZEOF_BDIGITS * yy > 1024*1024) {
 		rb_warn("in a**b, b may be too big");
+		odd = yy & 1;
 		d = (double)yy;
 		break;
@@ -1696,5 +1716,12 @@ rb_big_pow(VALUE x, VALUE y)
 	return rb_num_coerce_bin(x, y);
     }
-    return rb_float_new(pow(rb_big2dbl(x), d));
+    d = pow(rb_big2dbl(x), d);
+#ifdef __linux__
+    if (isnan(d)) {
+	d = (RBIGNUM(x)->sign || !odd) ? +1 : -1;
+	d /= 0.0;
+    }
+#endif
+    return rb_float_new(d);
 }
 
@@ -1871,4 +1898,17 @@ rb_big_xor(VALUE xx, VALUE yy)
 }
 
+static VALUE
+check_shift_width(VALUE y, VALUE x)
+{
+    long len = RBIGNUM(y)->len;
+    if (len) {
+	len = 1 << (len - 1) * BITSPERDIG;
+	if (len / BITSPERDIG > RBIGNUM(x)->len) {
+	    return RBIGNUM(x)->sign ? INT2FIX(0) : INT2FIX(-1);
+	}
+    }
+    return Qnil;
+}
+
 /*
  * call-seq:
@@ -1881,6 +1921,30 @@ VALUE
 rb_big_lshift(VALUE x, VALUE y)
 {
+    int shift;
+
+    for (;;) {
+	if (FIXNUM_P(y)) {
+	    shift = FIX2INT(y);
+	    break;
+	}
+	else if (TYPE(y) == T_BIGNUM) {
+	    if (!RBIGNUM(y)->sign) {
+		VALUE t = check_shift_width(y, x);
+		if (!NIL_P(t)) return t;
+	    }
+	    shift = big2ulong(y, "long", Qtrue);
+	    break;
+	}
+	y = rb_to_int(y);
+    }
+
+    if (shift < 0) return big_rshift(x, -shift);
+    return big_lshift(x, shift);
+}
+
+static VALUE
+big_lshift(VALUE x, unsigned int shift)
+{
     BDIGIT *xds, *zds;
-    int shift = NUM2INT(y);
     int s1 = shift/BITSPERDIG;
     int s2 = shift%BITSPERDIG;
@@ -1889,5 +1953,4 @@ rb_big_lshift(VALUE x, VALUE y)
     long len, i;
 
-    if (shift < 0) return rb_big_rshift(x, INT2FIX(-shift));
     len = RBIGNUM(x)->len;
     z = bignew(len+s1+1, RBIGNUM(x)->sign);
@@ -1913,9 +1976,33 @@ rb_big_lshift(VALUE x, VALUE y)
  */
 
-static VALUE
+VALUE
 rb_big_rshift(VALUE x, VALUE y)
 {
+    int shift;
+
+    for (;;) {
+	if (FIXNUM_P(y)) {
+	    shift = FIX2INT(y);
+	    break;
+	}
+	else if (TYPE(y) == T_BIGNUM) {
+	    if (RBIGNUM(y)->sign) {
+		VALUE t = check_shift_width(y, x);
+		if (!NIL_P(t)) return t;
+	    }
+	    shift = big2ulong(y, "long", Qtrue);
+	    break;
+	}
+	y = rb_to_int(y);
+    }
+
+    if (shift < 0) return big_lshift(x, -shift);
+    return big_rshift(x, shift);
+}
+
+static VALUE
+big_rshift(VALUE x, unsigned int shift)
+{
     BDIGIT *xds, *zds;
-    int shift = NUM2INT(y);
     long s1 = shift/BITSPERDIG;
     long s2 = shift%BITSPERDIG;
@@ -1925,6 +2012,4 @@ rb_big_rshift(VALUE x, VALUE y)
     volatile VALUE save_x;
 
-    if (shift < 0) return rb_big_lshift(x, INT2FIX(-shift));
-
     if (s1 > RBIGNUM(x)->len) {
 	if (RBIGNUM(x)->sign)
Index: numeric.c
===================================================================
--- numeric.c	(revision 12812)
+++ numeric.c	(working copy)
@@ -2592,5 +2600,6 @@ fix_xor(VALUE x, VALUE y)
 }
 
-static VALUE fix_rshift(VALUE, VALUE);
+static VALUE fix_lshift(long, unsigned long);
+static VALUE fix_rshift(long, unsigned long);
 
 /*
@@ -2602,15 +2611,23 @@ static VALUE fix_rshift(VALUE, VALUE);
 
 static VALUE
-fix_lshift(VALUE x, VALUE y)
+rb_fix_lshift(VALUE x, VALUE y)
 {
     long val, width;
 
     val = NUM2LONG(x);
-    width = NUM2LONG(y);
+    if (!FIXNUM_P(y))
+	return rb_big_lshift(rb_int2big(val), y);
+    width = FIX2LONG(y);
     if (width < 0)
-	return fix_rshift(x, LONG2FIX(-width));
+	return fix_rshift(val, (unsigned long)-width);
+    return fix_lshift(val, width);
+}
+
+static VALUE
+fix_lshift(long val, unsigned long width)
+{
     if (width > (sizeof(VALUE)*CHAR_BIT-1)
 	|| ((unsigned long)val)>>(sizeof(VALUE)*CHAR_BIT-1-width) > 0) {
-	return rb_big_lshift(rb_int2big(val), y);
+	return rb_big_lshift(rb_int2big(val), LONG2NUM(width));
     }
     val = val << width;
@@ -2626,13 +2643,21 @@ fix_lshift(VALUE x, VALUE y)
 
 static VALUE
-fix_rshift(VALUE x, VALUE y)
+rb_fix_rshift(VALUE x, VALUE y)
 {
     long i, val;
 
-    i = NUM2LONG(y);
-    if (i < 0)
-	return fix_lshift(x, LONG2FIX(-i));
-    if (i == 0) return x;
     val = FIX2LONG(x);
+    if (!FIXNUM_P(y))
+	return rb_big_rshift(rb_int2big(val), y);
+    i = FIX2LONG(y);
+    if (i == 0) return x;
+    if (i < 0)
+	return fix_lshift(val, (unsigned long)-i);
+    return fix_rshift(val, i);
+}
+
+static VALUE
+fix_rshift(long val, unsigned long i)
+{
     if (i >= sizeof(long)*CHAR_BIT-1) {
 	if (val < 0) return INT2FIX(-1);
@@ -2886,6 +2911,4 @@ static VALUE
 int_dotimes(VALUE num)
 {
-    VALUE val;
-
     RETURN_ENUMERATOR(num, 0, 0);
 
@@ -3106,6 +3129,6 @@ Init_Numeric(void)
     rb_define_method(rb_cFixnum, "[]", fix_aref, 1);
 
-    rb_define_method(rb_cFixnum, "<<", fix_lshift, 1);
-    rb_define_method(rb_cFixnum, ">>", fix_rshift, 1);
+    rb_define_method(rb_cFixnum, "<<", rb_fix_lshift, 1);
+    rb_define_method(rb_cFixnum, ">>", rb_fix_rshift, 1);
 
     rb_define_method(rb_cFixnum, "to_f", fix_to_f, 0);
Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(revision 12812)
+++ include/ruby/intern.h	(working copy)
@@ -115,4 +116,5 @@ VALUE rb_big_or(VALUE, VALUE);
 VALUE rb_big_xor(VALUE, VALUE);
 VALUE rb_big_lshift(VALUE, VALUE);
+VALUE rb_big_rshift(VALUE, VALUE);
 /* class.c */
 VALUE rb_class_boot(VALUE);
Index: test/ruby/test_integer.rb
===================================================================
--- test/ruby/test_integer.rb	(revision 12812)
+++ test/ruby/test_integer.rb	(working copy)
@@ -234,4 +234,8 @@ class TestInteger < Test::Unit::TestCase
       }
     }
+    assert_equal(0, 1 << -0x40000000)
+    assert_equal(0, 1 << -0x40000000)
+    assert_equal(0, 1 << -0x80000000)
+    assert_equal(0, 1 << -0x80000001)
   end
 
@@ -249,4 +253,5 @@ class TestInteger < Test::Unit::TestCase
       }
     }
+    assert_equal((1 << 0x40000000), (1 >> -0x40000000))
   end
 


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread