From 8b9a7b4e6f26a41e30c4a1dd0528a07b39ea2747 Mon Sep 17 00:00:00 2001 From: matz Date: Fri, 1 Jul 2005 08:54:04 +0000 Subject: * bignum.c (get2comp): revert all prior changes, and calculate proper 2's complement for negative numbers. backported from HEAD. git-svn-id: http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8@8693 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 ++++++ bignum.c | 45 ++++++++++++++++++++++----------------------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05e65cf3b..7f9e5f5f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Fri Jul 1 17:48:52 2005 Yukihiro Matsumoto + + * bignum.c (get2comp): revert all prior changes, and calculate + proper 2's complement for negative numbers. backported from + HEAD. + Fri Jul 1 15:50:12 2005 NAKAMURA Usaku * missing/erf.c: need to include some headers for some platforms. diff --git a/bignum.c b/bignum.c index 9272816fc..ae748fc86 100644 --- a/bignum.c +++ b/bignum.c @@ -65,10 +65,10 @@ rb_big_clone(x) return z; } +/* modify a bignum by 2's complement */ static void -get2comp(x, carry) /* get 2's complement */ +get2comp(x) VALUE x; - int carry; { long i = RBIGNUM(x)->len; BDIGIT *ds = BDIGITS(x); @@ -81,8 +81,7 @@ get2comp(x, carry) /* get 2's complement */ ds[i++] = BIGLO(num); num = BIGDN(num); } while (i < RBIGNUM(x)->len); - if (!carry) return; - if ((ds[RBIGNUM(x)->len-1] & (1<<(BITSPERDIG-1))) == 0) { + if (num != 0) { REALLOC_N(RBIGNUM(x)->digits, BDIGIT, ++RBIGNUM(x)->len); ds = BDIGITS(x); ds[RBIGNUM(x)->len-1] = RBIGNUM(x)->sign ? ~0 : 1; @@ -93,7 +92,7 @@ void rb_big_2comp(x) /* get 2's complement */ VALUE x; { - get2comp(x, Qtrue); + get2comp(x); } static VALUE @@ -1050,13 +1049,15 @@ rb_big_neg(x) VALUE x; { VALUE z = rb_big_clone(x); - long i = RBIGNUM(x)->len; - BDIGIT *ds = BDIGITS(z); + long i; + BDIGIT *ds; - if (!RBIGNUM(x)->sign) get2comp(z, Qtrue); + if (!RBIGNUM(x)->sign) get2comp(z); + ds = BDIGITS(z); + i = RBIGNUM(x)->len; while (i--) ds[i] = ~ds[i]; RBIGNUM(z)->sign = !RBIGNUM(z)->sign; - if (RBIGNUM(x)->sign) get2comp(z, Qtrue); + if (RBIGNUM(x)->sign) get2comp(z); return bignorm(z); } @@ -1648,11 +1649,11 @@ rb_big_and(xx, yy) } if (!RBIGNUM(y)->sign) { y = rb_big_clone(y); - get2comp(y, Qtrue); + get2comp(y); } if (!RBIGNUM(x)->sign) { x = rb_big_clone(x); - get2comp(x, Qtrue); + get2comp(x); } if (RBIGNUM(x)->len > RBIGNUM(y)->len) { l1 = RBIGNUM(y)->len; @@ -1677,7 +1678,7 @@ rb_big_and(xx, yy) for (; isign) get2comp(z, Qtrue); + if (!RBIGNUM(z)->sign) get2comp(z); return bignorm(z); } @@ -1702,14 +1703,13 @@ rb_big_or(xx, yy) if (FIXNUM_P(y)) { y = rb_int2big(FIX2LONG(y)); } - if (!RBIGNUM(y)->sign) { y = rb_big_clone(y); - get2comp(y, Qtrue); + get2comp(y); } if (!RBIGNUM(x)->sign) { x = rb_big_clone(x); - get2comp(x, Qtrue); + get2comp(x); } if (RBIGNUM(x)->len > RBIGNUM(y)->len) { l1 = RBIGNUM(y)->len; @@ -1734,7 +1734,7 @@ rb_big_or(xx, yy) for (; isign) get2comp(z, Qtrue); + if (!RBIGNUM(z)->sign) get2comp(z); return bignorm(z); } @@ -1761,14 +1761,13 @@ rb_big_xor(xx, yy) if (FIXNUM_P(y)) { y = rb_int2big(FIX2LONG(y)); } - if (!RBIGNUM(y)->sign) { y = rb_big_clone(y); - get2comp(y, Qtrue); + get2comp(y); } if (!RBIGNUM(x)->sign) { x = rb_big_clone(x); - get2comp(x, Qtrue); + get2comp(x); } if (RBIGNUM(x)->len > RBIGNUM(y)->len) { l1 = RBIGNUM(y)->len; @@ -1795,7 +1794,7 @@ rb_big_xor(xx, yy) for (; isign) get2comp(z, Qtrue); + if (!RBIGNUM(z)->sign) get2comp(z); return bignorm(z); } @@ -1867,7 +1866,7 @@ rb_big_rshift(x, y) } if (!RBIGNUM(x)->sign) { x = rb_big_clone(x); - get2comp(x, Qtrue); + get2comp(x); } xds = BDIGITS(x); i = RBIGNUM(x)->len; j = i - s1; @@ -1882,7 +1881,7 @@ rb_big_rshift(x, y) num = BIGUP(xds[i]); } if (!RBIGNUM(x)->sign) { - get2comp(z, Qfalse); + get2comp(z); } return bignorm(z); } @@ -1927,7 +1926,7 @@ rb_big_aref(x, y) if (!RBIGNUM(x)->sign) { if (s1 >= RBIGNUM(x)->len) return INT2FIX(1); x = rb_big_clone(x); - get2comp(x, Qtrue); + get2comp(x); } else { if (s1 >= RBIGNUM(x)->len) return INT2FIX(0); -- cgit