mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* bignum.c (bigsub_int): subtraction without making internal
bignum values. * bignum.c (bigadd_int): ditto for addition. * bignum.c (bigtrunc): declare inline. * bignum.c (rb_quad_pack): fix condition. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23238 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
5fc9b700bb
commit
dd54da6ede
2 changed files with 147 additions and 6 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
Tue Apr 21 01:25:16 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* bignum.c (bigsub_int): subtraction without making internal
|
||||||
|
bignum values.
|
||||||
|
|
||||||
|
* bignum.c (bigadd_int): ditto for addition.
|
||||||
|
|
||||||
|
* bignum.c (bigtrunc): declare inline.
|
||||||
|
|
||||||
|
* bignum.c (rb_quad_pack): fix condition.
|
||||||
|
|
||||||
Tue Apr 21 01:13:42 2009 Alexander Zavorine <alexandre.zavorine@nokia.com>
|
Tue Apr 21 01:13:42 2009 Alexander Zavorine <alexandre.zavorine@nokia.com>
|
||||||
|
|
||||||
* symbian/setup (config.h): added TIMET2NUM and NUM2TIMET to match the change in time.c
|
* symbian/setup (config.h): added TIMET2NUM and NUM2TIMET to match the change in time.c
|
||||||
|
|
142
bignum.c
142
bignum.c
|
@ -178,7 +178,7 @@ rb_big_2comp(VALUE x) /* get 2's complement */
|
||||||
get2comp(x);
|
get2comp(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static inline VALUE
|
||||||
bigtrunc(VALUE x)
|
bigtrunc(VALUE x)
|
||||||
{
|
{
|
||||||
long len = RBIGNUM_LEN(x);
|
long len = RBIGNUM_LEN(x);
|
||||||
|
@ -285,7 +285,7 @@ rb_int2inum(SIGNED_VALUE n)
|
||||||
return rb_int2big(n);
|
return rb_int2big(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LONG_LONG
|
#if SIZEOF_BDIGITS*2 == SIZEOF_LONG_LONG
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_quad_pack(char *buf, VALUE val)
|
rb_quad_pack(char *buf, VALUE val)
|
||||||
|
@ -1450,6 +1450,112 @@ bigsub(VALUE x, VALUE y)
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE bigadd_int(VALUE x, long y);
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
bigsub_int(VALUE x, long y0)
|
||||||
|
{
|
||||||
|
VALUE z;
|
||||||
|
BDIGIT *xds, *zds;
|
||||||
|
long xn;
|
||||||
|
BDIGIT_DBL_SIGNED num;
|
||||||
|
long i, y;
|
||||||
|
|
||||||
|
y = y0;
|
||||||
|
xds = BDIGITS(x);
|
||||||
|
xn = RBIGNUM_LEN(x);
|
||||||
|
|
||||||
|
z = bignew(xn, RBIGNUM_SIGN(x));
|
||||||
|
zds = BDIGITS(z);
|
||||||
|
|
||||||
|
#if SIZEOF_BDIGITS == SIZEOF_LONG
|
||||||
|
num = (BDIGIT_DBL_SIGNED)xds[0] - y;
|
||||||
|
if (xn == 1 && num < 0) {
|
||||||
|
for (i=0; i<xn; i++) {
|
||||||
|
}
|
||||||
|
RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(x));
|
||||||
|
zds[0] = -num;
|
||||||
|
return bignorm(z);
|
||||||
|
}
|
||||||
|
zds[0] = BIGLO(num);
|
||||||
|
num = BIGDN(num);
|
||||||
|
i = 1;
|
||||||
|
#else
|
||||||
|
num = 0;
|
||||||
|
for (i=0; i<sizeof(y)/sizeof(BDIGIT); i++) {
|
||||||
|
num += (BDIGIT_DBL_SIGNED)xds[i] - BIGLO(y);
|
||||||
|
zds[i] = BIGLO(num);
|
||||||
|
num = BIGDN(num);
|
||||||
|
y = BIGDN(y);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while (num && i < xn) {
|
||||||
|
num += xds[i];
|
||||||
|
zds[i++] = BIGLO(num);
|
||||||
|
num = BIGDN(num);
|
||||||
|
}
|
||||||
|
while (i < xn) {
|
||||||
|
zds[i] = xds[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (num < 0) {
|
||||||
|
z = bigsub(x, rb_int2big(y0));
|
||||||
|
}
|
||||||
|
return bignorm(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
bigadd_int(VALUE x, long y)
|
||||||
|
{
|
||||||
|
VALUE z;
|
||||||
|
BDIGIT *xds, *zds;
|
||||||
|
long xn, zn;
|
||||||
|
BDIGIT_DBL num;
|
||||||
|
long i;
|
||||||
|
|
||||||
|
xds = BDIGITS(x);
|
||||||
|
xn = RBIGNUM_LEN(x);
|
||||||
|
|
||||||
|
if (xn < 2) {
|
||||||
|
zn = 3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
zn = xn + 1;
|
||||||
|
}
|
||||||
|
z = bignew(zn, RBIGNUM_SIGN(x));
|
||||||
|
zds = BDIGITS(z);
|
||||||
|
|
||||||
|
#if SIZEOF_BDIGITS == SIZEOF_LONG
|
||||||
|
num = (BDIGIT_DBL)xds[0] + y;
|
||||||
|
zds[0] = BIGLO(num);
|
||||||
|
num = BIGDN(num);
|
||||||
|
i = 1;
|
||||||
|
#else
|
||||||
|
num = 0;
|
||||||
|
for (i=0; i<sizeof(y)/sizeof(BDIGIT); i++) {
|
||||||
|
num += (BDIGIT_DBL)xds[i] + BIGLO(y);
|
||||||
|
zds[i] = BIGLO(num);
|
||||||
|
num = BIGDN(num);
|
||||||
|
y = BIGDN(y);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while (num && i < xn) {
|
||||||
|
num += xds[i];
|
||||||
|
zds[i++] = BIGLO(num);
|
||||||
|
num = BIGDN(num);
|
||||||
|
}
|
||||||
|
if (num) zds[i++] = (BDIGIT)num;
|
||||||
|
else while (i < xn) {
|
||||||
|
zds[i] = xds[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
assert(i <= zn);
|
||||||
|
while (i < zn) {
|
||||||
|
zds[i++] = 0;
|
||||||
|
}
|
||||||
|
return bignorm(z);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bigadd_core(BDIGIT *xds, long xn, BDIGIT *yds, long yn, BDIGIT *zds, long zn)
|
bigadd_core(BDIGIT *xds, long xn, BDIGIT *yds, long yn, BDIGIT *zds, long zn)
|
||||||
{
|
{
|
||||||
|
@ -1521,10 +1627,22 @@ bigadd(VALUE x, VALUE y, int sign)
|
||||||
VALUE
|
VALUE
|
||||||
rb_big_plus(VALUE x, VALUE y)
|
rb_big_plus(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
|
long n;
|
||||||
|
|
||||||
switch (TYPE(y)) {
|
switch (TYPE(y)) {
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
y = rb_int2big(FIX2LONG(y));
|
n = FIX2LONG(y);
|
||||||
/* fall through */
|
if ((n > 0) != RBIGNUM_SIGN(x)) {
|
||||||
|
if (n < 0) {
|
||||||
|
n = -n;
|
||||||
|
}
|
||||||
|
return bigsub_int(x, n);
|
||||||
|
}
|
||||||
|
if (n < 0) {
|
||||||
|
n = -n;
|
||||||
|
}
|
||||||
|
return bigadd_int(x, n);
|
||||||
|
|
||||||
case T_BIGNUM:
|
case T_BIGNUM:
|
||||||
return bignorm(bigadd(x, y, 1));
|
return bignorm(bigadd(x, y, 1));
|
||||||
|
|
||||||
|
@ -1546,10 +1664,22 @@ rb_big_plus(VALUE x, VALUE y)
|
||||||
VALUE
|
VALUE
|
||||||
rb_big_minus(VALUE x, VALUE y)
|
rb_big_minus(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
|
long n;
|
||||||
|
|
||||||
switch (TYPE(y)) {
|
switch (TYPE(y)) {
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
y = rb_int2big(FIX2LONG(y));
|
n = FIX2LONG(y);
|
||||||
/* fall through */
|
if ((n > 0) != RBIGNUM_SIGN(x)) {
|
||||||
|
if (n < 0) {
|
||||||
|
n = -n;
|
||||||
|
}
|
||||||
|
return bigadd_int(x, n);
|
||||||
|
}
|
||||||
|
if (n < 0) {
|
||||||
|
n = -n;
|
||||||
|
}
|
||||||
|
return bigsub_int(x, n);
|
||||||
|
|
||||||
case T_BIGNUM:
|
case T_BIGNUM:
|
||||||
return bignorm(bigadd(x, y, 0));
|
return bignorm(bigadd(x, y, 0));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue