* bignum.c (bigand_int): new function to calculate bignum and
fixnum without allocating internal bignum. * bignum.c (bigor_int): ditto. * bignum.c (bigxor_int): ditto. * bignum.c (bigand_int): even less object allocation. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23596 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
72f4e2c709
commit
80ad1473cf
11
ChangeLog
11
ChangeLog
@ -2,6 +2,17 @@ Wed May 27 23:00:38 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
|||||||
|
|
||||||
* parse.y (struct parser_params): lex_gets_ptr should be long.
|
* parse.y (struct parser_params): lex_gets_ptr should be long.
|
||||||
|
|
||||||
|
Wed May 27 18:00:15 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* bignum.c (bigand_int): new function to calculate bignum and
|
||||||
|
fixnum without allocating internal bignum.
|
||||||
|
|
||||||
|
* bignum.c (bigor_int): ditto.
|
||||||
|
|
||||||
|
* bignum.c (bigxor_int): ditto.
|
||||||
|
|
||||||
|
* bignum.c (bigand_int): even less object allocation.
|
||||||
|
|
||||||
Wed May 27 14:08:39 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Wed May 27 14:08:39 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* st.c (st_insert2): new function with processing new key,
|
* st.c (st_insert2): new function with processing new key,
|
||||||
|
156
bignum.c
156
bignum.c
@ -2530,7 +2530,7 @@ rb_big_pow(VALUE x, VALUE y)
|
|||||||
return DBL2NUM(pow(rb_big2dbl(x), d));
|
return DBL2NUM(pow(rb_big2dbl(x), d));
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static inline VALUE
|
||||||
bit_coerce(VALUE x)
|
bit_coerce(VALUE x)
|
||||||
{
|
{
|
||||||
while (!FIXNUM_P(x) && TYPE(x) != T_BIGNUM) {
|
while (!FIXNUM_P(x) && TYPE(x) != T_BIGNUM) {
|
||||||
@ -2542,6 +2542,50 @@ bit_coerce(VALUE x)
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
bigand_int(VALUE x, long y)
|
||||||
|
{
|
||||||
|
VALUE z;
|
||||||
|
BDIGIT *xds, *zds;
|
||||||
|
long xn, zn;
|
||||||
|
long i;
|
||||||
|
char sign;
|
||||||
|
|
||||||
|
if (y == 0) return INT2FIX(0);
|
||||||
|
sign = (y > 0);
|
||||||
|
xds = BDIGITS(x);
|
||||||
|
zn = xn = RBIGNUM_LEN(x);
|
||||||
|
#if SIZEOF_BDIGITS == SIZEOF_LONG
|
||||||
|
if (sign) {
|
||||||
|
y &= xds[0];
|
||||||
|
return LONG2NUM(y);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
z = bignew(zn, RBIGNUM_SIGN(x) || sign);
|
||||||
|
zds = BDIGITS(z);
|
||||||
|
|
||||||
|
#if SIZEOF_BDIGITS == SIZEOF_LONG
|
||||||
|
i = 1;
|
||||||
|
zds[0] = xds[0] & y;
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
BDIGIT_DBL num = y;
|
||||||
|
|
||||||
|
for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) {
|
||||||
|
zds[i] = xds[i] & BIGLO(num);
|
||||||
|
num = BIGDN(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while (i < xn) {
|
||||||
|
zds[i] = sign?0:xds[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (!RBIGNUM_SIGN(z)) get2comp(z);
|
||||||
|
return bignorm(z);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* big & numeric => integer
|
* big & numeric => integer
|
||||||
@ -2559,17 +2603,17 @@ rb_big_and(VALUE xx, VALUE yy)
|
|||||||
|
|
||||||
x = xx;
|
x = xx;
|
||||||
y = bit_coerce(yy);
|
y = bit_coerce(yy);
|
||||||
|
if (!RBIGNUM_SIGN(x)) {
|
||||||
|
x = rb_big_clone(x);
|
||||||
|
get2comp(x);
|
||||||
|
}
|
||||||
if (FIXNUM_P(y)) {
|
if (FIXNUM_P(y)) {
|
||||||
y = rb_int2big(FIX2LONG(y));
|
return bigand_int(x, FIX2LONG(y));
|
||||||
}
|
}
|
||||||
if (!RBIGNUM_SIGN(y)) {
|
if (!RBIGNUM_SIGN(y)) {
|
||||||
y = rb_big_clone(y);
|
y = rb_big_clone(y);
|
||||||
get2comp(y);
|
get2comp(y);
|
||||||
}
|
}
|
||||||
if (!RBIGNUM_SIGN(x)) {
|
|
||||||
x = rb_big_clone(x);
|
|
||||||
get2comp(x);
|
|
||||||
}
|
|
||||||
if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
|
if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
|
||||||
l1 = RBIGNUM_LEN(y);
|
l1 = RBIGNUM_LEN(y);
|
||||||
l2 = RBIGNUM_LEN(x);
|
l2 = RBIGNUM_LEN(x);
|
||||||
@ -2597,6 +2641,42 @@ rb_big_and(VALUE xx, VALUE yy)
|
|||||||
return bignorm(z);
|
return bignorm(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
bigor_int(VALUE x, long y)
|
||||||
|
{
|
||||||
|
VALUE z;
|
||||||
|
BDIGIT *xds, *zds;
|
||||||
|
long xn, zn;
|
||||||
|
long i;
|
||||||
|
char sign;
|
||||||
|
|
||||||
|
sign = (y >= 0);
|
||||||
|
xds = BDIGITS(x);
|
||||||
|
zn = xn = RBIGNUM_LEN(x);
|
||||||
|
z = bignew(zn, RBIGNUM_SIGN(x) && sign);
|
||||||
|
zds = BDIGITS(z);
|
||||||
|
|
||||||
|
#if SIZEOF_BDIGITS == SIZEOF_LONG
|
||||||
|
i = 1;
|
||||||
|
zds[0] = xds[0] | y;
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
BDIGIT_DBL num = y;
|
||||||
|
|
||||||
|
for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) {
|
||||||
|
zds[i] = xds[i] | BIGLO(num);
|
||||||
|
num = BIGDN(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while (i < xn) {
|
||||||
|
zds[i] = sign?xds[i]:(BDIGIT)(BIGRAD-1);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (!RBIGNUM_SIGN(z)) get2comp(z);
|
||||||
|
return bignorm(z);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* big | numeric => integer
|
* big | numeric => integer
|
||||||
@ -2614,18 +2694,18 @@ rb_big_or(VALUE xx, VALUE yy)
|
|||||||
|
|
||||||
x = xx;
|
x = xx;
|
||||||
y = bit_coerce(yy);
|
y = bit_coerce(yy);
|
||||||
if (FIXNUM_P(y)) {
|
|
||||||
y = rb_int2big(FIX2LONG(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!RBIGNUM_SIGN(y)) {
|
|
||||||
y = rb_big_clone(y);
|
|
||||||
get2comp(y);
|
|
||||||
}
|
|
||||||
if (!RBIGNUM_SIGN(x)) {
|
if (!RBIGNUM_SIGN(x)) {
|
||||||
x = rb_big_clone(x);
|
x = rb_big_clone(x);
|
||||||
get2comp(x);
|
get2comp(x);
|
||||||
}
|
}
|
||||||
|
if (FIXNUM_P(y)) {
|
||||||
|
return bigor_int(x, FIX2LONG(y));
|
||||||
|
}
|
||||||
|
if (!RBIGNUM_SIGN(y)) {
|
||||||
|
y = rb_big_clone(y);
|
||||||
|
get2comp(y);
|
||||||
|
}
|
||||||
if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
|
if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
|
||||||
l1 = RBIGNUM_LEN(y);
|
l1 = RBIGNUM_LEN(y);
|
||||||
l2 = RBIGNUM_LEN(x);
|
l2 = RBIGNUM_LEN(x);
|
||||||
@ -2650,10 +2730,44 @@ rb_big_or(VALUE xx, VALUE yy)
|
|||||||
zds[i] = sign?ds2[i]:(BDIGIT)(BIGRAD-1);
|
zds[i] = sign?ds2[i]:(BDIGIT)(BIGRAD-1);
|
||||||
}
|
}
|
||||||
if (!RBIGNUM_SIGN(z)) get2comp(z);
|
if (!RBIGNUM_SIGN(z)) get2comp(z);
|
||||||
|
|
||||||
return bignorm(z);
|
return bignorm(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
bigxor_int(VALUE x, long y)
|
||||||
|
{
|
||||||
|
VALUE z;
|
||||||
|
BDIGIT *xds, *zds;
|
||||||
|
long xn, zn;
|
||||||
|
long i;
|
||||||
|
char sign;
|
||||||
|
|
||||||
|
sign = (y >= 0) ? 1 : 0;
|
||||||
|
xds = BDIGITS(x);
|
||||||
|
zn = xn = RBIGNUM_LEN(x);
|
||||||
|
z = bignew(zn, !(RBIGNUM_SIGN(x) ^ sign));
|
||||||
|
zds = BDIGITS(z);
|
||||||
|
|
||||||
|
#if SIZEOF_BDIGITS == SIZEOF_LONG
|
||||||
|
i = 1;
|
||||||
|
zds[0] = xds[0] ^ y;
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
BDIGIT_DBL num = y;
|
||||||
|
|
||||||
|
for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) {
|
||||||
|
zds[i] = xds[i] ^ BIGLO(num);
|
||||||
|
num = BIGDN(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while (i < xn) {
|
||||||
|
zds[i] = sign?xds[i]:~xds[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (!RBIGNUM_SIGN(z)) get2comp(z);
|
||||||
|
return bignorm(z);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* big ^ numeric => integer
|
* big ^ numeric => integer
|
||||||
@ -2672,18 +2786,18 @@ rb_big_xor(VALUE xx, VALUE yy)
|
|||||||
|
|
||||||
x = xx;
|
x = xx;
|
||||||
y = bit_coerce(yy);
|
y = bit_coerce(yy);
|
||||||
if (FIXNUM_P(y)) {
|
|
||||||
y = rb_int2big(FIX2LONG(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!RBIGNUM_SIGN(y)) {
|
|
||||||
y = rb_big_clone(y);
|
|
||||||
get2comp(y);
|
|
||||||
}
|
|
||||||
if (!RBIGNUM_SIGN(x)) {
|
if (!RBIGNUM_SIGN(x)) {
|
||||||
x = rb_big_clone(x);
|
x = rb_big_clone(x);
|
||||||
get2comp(x);
|
get2comp(x);
|
||||||
}
|
}
|
||||||
|
if (FIXNUM_P(y)) {
|
||||||
|
return bigxor_int(x, FIX2LONG(y));
|
||||||
|
}
|
||||||
|
if (!RBIGNUM_SIGN(y)) {
|
||||||
|
y = rb_big_clone(y);
|
||||||
|
get2comp(y);
|
||||||
|
}
|
||||||
if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
|
if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
|
||||||
l1 = RBIGNUM_LEN(y);
|
l1 = RBIGNUM_LEN(y);
|
||||||
l2 = RBIGNUM_LEN(x);
|
l2 = RBIGNUM_LEN(x);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user