diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-06-29 16:58:58 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-06-29 16:58:58 +0000 |
commit | b1e052d0805b97c83fd0ff04580d4c5d555613c7 (patch) | |
tree | a65d3961485d778e6d8c3bd8575ffd063d9d47b4 | |
parent | 3c9f0334a526fa72e72c3ebf7171cb257e8052be (diff) | |
download | ruby-b1e052d0805b97c83fd0ff04580d4c5d555613c7.tar.gz |
* bignum.c (big_rshift): Use abs2twocomp and twocomp2abs_bang.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41698 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | bignum.c | 29 |
2 files changed, 16 insertions, 17 deletions
@@ -1,3 +1,7 @@ +Sun Jun 30 01:57:08 2013 Tanaka Akira <akr@fsij.org> + + * bignum.c (big_rshift): Use abs2twocomp and twocomp2abs_bang. + Sun Jun 30 00:14:20 2013 Tanaka Akira <akr@fsij.org> * bignum.c (RBIGNUM_SET_NEGATIVE_SIGN): New macro. @@ -5163,33 +5163,28 @@ big_rshift(VALUE x, unsigned long shift) long s1 = shift/BITSPERDIG; int s2 = (int)(shift%BITSPERDIG); VALUE z; - long i, j; - volatile VALUE save_x; + long j; + long xl; + BDIGIT hibitsx; if (s1 > RBIGNUM_LEN(x)) { - if (RBIGNUM_SIGN(x)) + if (RBIGNUM_POSITIVE_P(x) || bary_zero_p(BDIGITS(x), RBIGNUM_LEN(x))) return INT2FIX(0); else return INT2FIX(-1); } - if (!RBIGNUM_SIGN(x)) { - x = rb_big_clone(x); - get2comp(x); - } - save_x = x; + hibitsx = abs2twocomp(&x, &xl); xds = BDIGITS(x); - i = RBIGNUM_LEN(x); j = i - s1; - if (j == 0) { - if (RBIGNUM_SIGN(x)) return INT2FIX(0); + j = xl - s1; + if (j <= 0) { + if (!hibitsx) return INT2FIX(0); else return INT2FIX(-1); } - z = bignew(j, RBIGNUM_SIGN(x)); + z = bignew(j, 0); zds = BDIGITS(z); - bary_small_rshift(zds, xds+s1, j, s2, !RBIGNUM_SIGN(x)); - if (!RBIGNUM_SIGN(x)) { - get2comp(z); - } - RB_GC_GUARD(save_x); + bary_small_rshift(zds, xds+s1, j, s2, hibitsx != 0); + twocomp2abs_bang(z, hibitsx != 0); + RB_GC_GUARD(x); return z; } |