mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* bignum.c (bary_subb): Support xn < yn.
(bigsub_core): Removed. (bigsub): Don't compare before subtraction. Just subtract and get the two's complement if the subtraction causes a borrow. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41962 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
651f762c17
commit
b0eacd027a
2 changed files with 42 additions and 38 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Sun Jul 14 22:21:11 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* bignum.c (bary_subb): Support xn < yn.
|
||||||
|
(bigsub_core): Removed.
|
||||||
|
(bigsub): Don't compare before subtraction. Just subtract and
|
||||||
|
get the two's complement if the subtraction causes a borrow.
|
||||||
|
|
||||||
Sun Jul 14 00:36:03 2013 Tanaka Akira <akr@fsij.org>
|
Sun Jul 14 00:36:03 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* bignum.c (DIGSPERLONG): Unused macro removed.
|
* bignum.c (DIGSPERLONG): Unused macro removed.
|
||||||
|
|
59
bignum.c
59
bignum.c
|
@ -1353,22 +1353,34 @@ bary_subb(BDIGIT *zds, size_t zn, BDIGIT *xds, size_t xn, BDIGIT *yds, size_t yn
|
||||||
{
|
{
|
||||||
BDIGIT_DBL_SIGNED num;
|
BDIGIT_DBL_SIGNED num;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
size_t sn;
|
||||||
|
|
||||||
assert(yn <= xn);
|
|
||||||
assert(xn <= zn);
|
assert(xn <= zn);
|
||||||
|
assert(yn <= zn);
|
||||||
|
|
||||||
|
sn = xn < yn ? xn : yn;
|
||||||
|
|
||||||
num = borrow ? -1 : 0;
|
num = borrow ? -1 : 0;
|
||||||
for (i = 0; i < yn; i++) {
|
for (i = 0; i < sn; i++) {
|
||||||
num += (BDIGIT_DBL_SIGNED)xds[i] - yds[i];
|
num += (BDIGIT_DBL_SIGNED)xds[i] - yds[i];
|
||||||
zds[i] = BIGLO(num);
|
zds[i] = BIGLO(num);
|
||||||
num = BIGDN(num);
|
num = BIGDN(num);
|
||||||
}
|
}
|
||||||
|
if (yn <= xn) {
|
||||||
for (; i < xn; i++) {
|
for (; i < xn; i++) {
|
||||||
if (num == 0) goto num_is_zero;
|
if (num == 0) goto num_is_zero;
|
||||||
num += xds[i];
|
num += xds[i];
|
||||||
zds[i] = BIGLO(num);
|
zds[i] = BIGLO(num);
|
||||||
num = BIGDN(num);
|
num = BIGDN(num);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (; i < yn; i++) {
|
||||||
|
num -= yds[i];
|
||||||
|
zds[i] = BIGLO(num);
|
||||||
|
num = BIGDN(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (num == 0) goto num_is_zero;
|
if (num == 0) goto num_is_zero;
|
||||||
for (; i < zn; i++) {
|
for (; i < zn; i++) {
|
||||||
zds[i] = BDIGMAX;
|
zds[i] = BDIGMAX;
|
||||||
|
@ -4237,42 +4249,27 @@ rb_big_neg(VALUE x)
|
||||||
return bignorm(z);
|
return bignorm(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
bigsub_core(BDIGIT *xds, long xn, BDIGIT *yds, long yn, BDIGIT *zds, long zn)
|
|
||||||
{
|
|
||||||
bary_sub(zds, zn, xds, xn, yds, yn);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
bigsub(VALUE x, VALUE y)
|
bigsub(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
VALUE z = 0;
|
VALUE z;
|
||||||
long i = RBIGNUM_LEN(x);
|
BDIGIT *xds, *yds, *zds;
|
||||||
BDIGIT *xds, *yds;
|
long xn, yn, zn;
|
||||||
|
|
||||||
|
xn = RBIGNUM_LEN(x);
|
||||||
|
yn = RBIGNUM_LEN(y);
|
||||||
|
zn = xn < yn ? yn : xn;
|
||||||
|
|
||||||
|
z = bignew(zn, 1);
|
||||||
|
|
||||||
/* if x is smaller than y, swap */
|
|
||||||
if (RBIGNUM_LEN(x) < RBIGNUM_LEN(y)) {
|
|
||||||
z = x; x = y; y = z; /* swap x y */
|
|
||||||
}
|
|
||||||
else if (RBIGNUM_LEN(x) == RBIGNUM_LEN(y)) {
|
|
||||||
xds = BDIGITS(x);
|
xds = BDIGITS(x);
|
||||||
yds = BDIGITS(y);
|
yds = BDIGITS(y);
|
||||||
while (i > 0) {
|
zds = BDIGITS(z);
|
||||||
i--;
|
|
||||||
if (xds[i] > yds[i]) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (xds[i] < yds[i]) {
|
|
||||||
z = x; x = y; y = z; /* swap x y */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
z = bignew(RBIGNUM_LEN(x), z==0);
|
if (bary_sub(zds, zn, xds, xn, yds, yn)) {
|
||||||
bigsub_core(BDIGITS(x), RBIGNUM_LEN(x),
|
bary_2comp(zds, zn);
|
||||||
BDIGITS(y), RBIGNUM_LEN(y),
|
RBIGNUM_SET_NEGATIVE_SIGN(z);
|
||||||
BDIGITS(z), RBIGNUM_LEN(z));
|
}
|
||||||
|
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue