[#31143] m {|(*,(*)),|} — Tanaka Akira <akr@...>
m {|(*,(*)),|} で SEGV します。
[#31164] ruby_set_current_source remains in intern.h — Masahiro Sakai (酒井政裕) <masahiro.sakai@...>
酒井です。
[#31166] is_ruby_native_thread() — Masahiro Sakai (酒井政裕) <masahiro.sakai@...>
酒井です。
なかだです。
永井@知能.九工大です.
なかだです。
永井@知能.九工大です.
ささだです。
[#31168] 構造体オブジェクトのcloneメソッド呼び出しでメモリリーク発生 — m-ohkubo@... (Mitsuhiko OHKUBO)
大久保といいます。はじめまして。
なかだです。
大久保です。よろしくお願いします。
[#31190] 0x3fffffffffffffff.succ — Tanaka Akira <akr@...>
LP64 環境で 0x3fffffffffffffff.succ が -4611686018427387904
[#31214] Warning: OpenSSL::PKCS7::PKCS7 is deprecated after Ruby 1.9; use OpenSSL::PKCS7 instead — Kazuhiro NISHIYAMA <zn@...>
西山和広です。
[#31222] trunk: バグを指摘している警告 — pegacorn <subscriber.jp@...>
trunk で -Wall を付けてコンパイルしてみると、バグを指摘している警告が
From: pegacorn <subscriber.jp@gmail.com>
[#31242] p(65536**(1<<29)) stalls — "Yusuke ENDOH" <mame@...>
遠藤と申します。
[#31244] shift — Tanaka Akira <akr@...>
-O0 で、以下のようにすると SEGV になります。
なかだです。
In article <200707180743.l6I7hXic031558@sharui.nakada.kanuma.tochigi.jp>,
[#31285] p()#=>[] — eklerni <eklerni@...>
松尾といいます。
[#31292] ParseDate.parsedate("Tuesday, July 6th, 2007, 18:35:20 UTC") — Tanaka Akira <akr@...>
ParseDate のマニュアルにある以下の例を動かすと、示された結果
[#31298] retryの使い方 — eklerni <eklerni@...>
松尾といいます。
ささだです。
松尾です、返信ありがとうございます。
Yuguiといいます。
松尾といいます。
In article <46A909DD.1070405@for.mail-box.ne.jp>,
Tanaka Akira さんは書きました:
In article <46A92530.80507@for.mail-box.ne.jp>,
Tanaka Akira さんは書きました:
In article <46AD7A16.8080509@for.mail-box.ne.jp>,
松尾です。
ささだです。
From:eklerni
まつもと ゆきひろです
In article <E1ILDTi-0005T6-Be@x31>,
まつもと ゆきひろです
In article <E1ILKn6-0003Nv-0f@x31>,
まつもと ゆきひろです
In article <E1ILVN9-0006xJ-7I@x31>,
In article <E1ILq4x-0002Bs-Lg@x31>,
まつもと ゆきひろです
In article <E1ILweZ-00008I-Tu@x31>,
まつもと ゆきひろです
In article <E1ILyGa-0000ug-Qd@x31>,
まつもと ゆきひろです
In article <E1IM1W9-0001uC-Bz@x31>,
まつもと ゆきひろです
[ruby-dev:31245] Re: shift
なかだです。
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はできる。
中田 伸悦