aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-27 14:59:50 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-27 14:59:50 +0000
commitef18728433d0418b2e002eb46f7abc321ff2d535 (patch)
treeec64d3a79b9267aa2eaa868eeef02f43c1ddb87e
parentcd6912a5952e719c643d319d7120659ddd3de1c8 (diff)
downloadruby-ef18728433d0418b2e002eb46f7abc321ff2d535.tar.gz
* bignum.c (abs2twocomp_bang): Removed.
(abs2twocomp): Take n_ret argument to return actual length. (rb_big_and): Follow above change. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41681 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog6
-rw-r--r--bignum.c47
2 files changed, 24 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 658b0a9bb9..28b44e5e75 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Thu Jun 27 23:58:13 2013 Tanaka Akira <akr@fsij.org>
+
+ * bignum.c (abs2twocomp_bang): Removed.
+ (abs2twocomp): Take n_ret argument to return actual length.
+ (rb_big_and): Follow above change.
+
Thu Jun 27 22:52:19 2013 Tanaka Akira <akr@fsij.org>
* bignum.c (get2comp): Use bary_2comp.
diff --git a/bignum.c b/bignum.c
index e2e172e0fc..badbb816f6 100644
--- a/bignum.c
+++ b/bignum.c
@@ -304,37 +304,24 @@ rb_big_2comp(VALUE x) /* get 2's complement */
}
static BDIGIT
-abs2twocomp_bang(VALUE x)
+abs2twocomp(VALUE *xp, long *n_ret)
{
- long numbdigits = RBIGNUM_LEN(x);
- long n;
+ VALUE x = *xp;
+ long n = RBIGNUM_LEN(x);
BDIGIT *ds = BDIGITS(x);
- BDIGIT hibits;
-
- n = numbdigits;
+ BDIGIT hibits = 0;
while (0 < n && ds[n-1] == 0)
n--;
- if (n == 0 || RBIGNUM_POSITIVE_P(x))
- hibits = 0;
- else {
+ if (n != 0 && RBIGNUM_NEGATIVE_P(x)) {
+ VALUE z = bignew_1(CLASS_OF(x), n, 0);
+ MEMCPY(BDIGITS(z), ds, BDIGIT, n);
+ bary_2comp(BDIGITS(z), n);
hibits = BDIGMAX;
- bary_2comp(ds, numbdigits);
- }
-
- return hibits;
-}
-
-static BDIGIT
-abs2twocomp(VALUE *xp)
-{
- VALUE x = *xp;
- BDIGIT hibits = 0;
- if (RBIGNUM_NEGATIVE_P(x)) {
- *xp = x = rb_big_clone(x);
- hibits = abs2twocomp_bang(x);
+ *xp = z;
}
+ *n_ret = n;
return hibits;
}
@@ -4730,27 +4717,29 @@ rb_big_and(VALUE x, VALUE y)
{
VALUE z;
BDIGIT *ds1, *ds2, *zds;
- long i, l1, l2;
+ long i, xl, yl, l1, l2;
BDIGIT hibitsx, hibitsy;
BDIGIT hibits1, hibits2;
VALUE tmpv;
BDIGIT tmph;
+ long tmpl;
if (!FIXNUM_P(y) && !RB_TYPE_P(y, T_BIGNUM)) {
return rb_num_coerce_bit(x, y, '&');
}
- hibitsx = abs2twocomp(&x);
+ hibitsx = abs2twocomp(&x, &xl);
if (FIXNUM_P(y)) {
return bigand_int(x, FIX2LONG(y));
}
- hibitsy = abs2twocomp(&y);
- if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
+ hibitsy = abs2twocomp(&y, &yl);
+ if (xl > yl) {
tmpv = x; x = y; y = tmpv;
+ tmpl = xl; xl = yl; yl = tmpl;
tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
}
- l1 = RBIGNUM_LEN(x);
- l2 = RBIGNUM_LEN(y);
+ l1 = xl;
+ l2 = yl;
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
hibits1 = hibitsx;