* bignum.c (bigand_int): Add arguments, xn and hibitsx.

Use twocomp2abs_bang.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41683 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2013-06-27 23:07:59 +00:00
parent ef18728433
commit 43e4de376b
2 changed files with 21 additions and 14 deletions

View File

@ -1,3 +1,8 @@
Fri Jun 28 08:06:22 2013 Tanaka Akira <akr@fsij.org>
* bignum.c (bigand_int): Add arguments, xn and hibitsx.
Use twocomp2abs_bang.
Thu Jun 27 23:58:13 2013 Tanaka Akira <akr@fsij.org> Thu Jun 27 23:58:13 2013 Tanaka Akira <akr@fsij.org>
* bignum.c (abs2twocomp_bang): Removed. * bignum.c (abs2twocomp_bang): Removed.

View File

@ -4653,30 +4653,32 @@ rb_big_pow(VALUE x, VALUE y)
} }
static VALUE static VALUE
bigand_int(VALUE x, long y) bigand_int(VALUE x, long xn, BDIGIT hibitsx, long y)
{ {
VALUE z; VALUE z;
BDIGIT *xds, *zds; BDIGIT *xds, *zds;
long xn, zn; long zn;
long i; long i;
char sign; BDIGIT hibitsy;
if (y == 0) return INT2FIX(0); if (y == 0) return INT2FIX(0);
sign = (y > 0); if (xn == 0) return LONG2NUM((long)(hibitsx & y));
hibitsy = 0 <= y ? 0 : BDIGMAX;
xds = BDIGITS(x); xds = BDIGITS(x);
zn = xn = RBIGNUM_LEN(x);
#if SIZEOF_BDIGITS >= SIZEOF_LONG #if SIZEOF_BDIGITS >= SIZEOF_LONG
if (sign) { if (!hibitsy) {
y &= xds[0]; y &= xds[0];
return LONG2NUM(y); return LONG2NUM(y);
} }
#endif #endif
zn = xn;
#if SIZEOF_BDIGITS < SIZEOF_LONG #if SIZEOF_BDIGITS < SIZEOF_LONG
if (RBIGNUM_NEGATIVE_P(x) && zn < bdigit_roomof(SIZEOF_LONG)) if (hibitsx && zn < bdigit_roomof(SIZEOF_LONG))
zn = bdigit_roomof(SIZEOF_LONG); zn = bdigit_roomof(SIZEOF_LONG);
#endif #endif
z = bignew(zn, RBIGNUM_SIGN(x) || sign); z = bignew(zn, 0);
zds = BDIGITS(z); zds = BDIGITS(z);
#if SIZEOF_BDIGITS >= SIZEOF_LONG #if SIZEOF_BDIGITS >= SIZEOF_LONG
@ -4690,18 +4692,18 @@ bigand_int(VALUE x, long y)
} }
for (; i < zn; i++) { for (; i < zn; i++) {
if (y == 0 || y == -1) break; if (y == 0 || y == -1) break;
zds[i] = RBIGNUM_NEGATIVE_P(x) ? BIGLO(y) : 0; zds[i] = hibitsx & BIGLO(y);
y = BIGDN(y); y = BIGDN(y);
} }
#endif #endif
for (;i < xn; i++) { for (;i < xn; i++) {
zds[i] = sign?0:xds[i]; zds[i] = xds[i] & hibitsy;
} }
for (;i < zn; i++) { for (;i < zn; i++) {
zds[i] = (!sign && RBIGNUM_NEGATIVE_P(x)) ? BDIGMAX : 0; zds[i] = hibitsx & hibitsy;
} }
if (!RBIGNUM_SIGN(z)) get2comp(z); twocomp2abs_bang(z, hibitsx && hibitsy);
RB_GC_GUARD(x);
return bignorm(z); return bignorm(z);
} }
@ -4730,7 +4732,7 @@ rb_big_and(VALUE x, VALUE y)
hibitsx = abs2twocomp(&x, &xl); hibitsx = abs2twocomp(&x, &xl);
if (FIXNUM_P(y)) { if (FIXNUM_P(y)) {
return bigand_int(x, FIX2LONG(y)); return bigand_int(x, xl, hibitsx, FIX2LONG(y));
} }
hibitsy = abs2twocomp(&y, &yl); hibitsy = abs2twocomp(&y, &yl);
if (xl > yl) { if (xl > yl) {