From 63dd3e7ef9c1f2b839072003cb1696282520ffd1 Mon Sep 17 00:00:00 2001 From: akr Date: Thu, 13 Jun 2013 12:26:33 +0000 Subject: * bignum.c (bigdivrem): Refactored to use ALLOCV_N for temporally buffers. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41278 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- bignum.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'bignum.c') diff --git a/bignum.c b/bignum.c index 5df4958aca..d2c1e865c7 100644 --- a/bignum.c +++ b/bignum.c @@ -3754,16 +3754,19 @@ static VALUE bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp) { struct big_div_struct bds; - long nx = RBIGNUM_LEN(x), ny = RBIGNUM_LEN(y); + long nx = RBIGNUM_LEN(x), ny = RBIGNUM_LEN(y), nz; long i, j; - VALUE z, yy, zz; - BDIGIT *xds, *yds, *zds, *tds; + VALUE z, zz; + VALUE tmpy = 0, tmpz = 0; + BDIGIT *xds, *yds, *zds, *tds, *qds; BDIGIT_DBL t2; BDIGIT dd, q; if (BIGZEROP(y)) rb_num_zerodiv(); xds = BDIGITS(x); yds = BDIGITS(y); + while (0 < nx && !xds[nx-1]) nx--; + while (!yds[ny-1]) ny--; if (nx < ny || (nx == ny && xds[nx - 1] < yds[ny - 1])) { if (divp) *divp = rb_int2big(0); if (modp) *modp = x; @@ -3788,17 +3791,15 @@ bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp) return Qnil; } - z = bignew(nx==ny?nx+2:nx+1, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y)); - zds = BDIGITS(z); + nz = nx==ny ? nx+2 : nx+1; + zds = ALLOCV_N(BDIGIT, tmpz, nz); if (nx==ny) zds[nx+1] = 0; - while (!yds[ny-1]) ny--; q = yds[ny-1]; dd = nlz(q); q <<= dd; if (dd) { - yy = rb_big_clone(y); - tds = BDIGITS(yy); + tds = ALLOCV_N(BDIGIT, tmpy, RBIGNUM_LEN(y)); j = 0; t2 = 0; while (j 10000 || ny > 10000) { retry: @@ -3845,16 +3845,14 @@ bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp) } if (divp) { /* move quotient down in z */ - *divp = zz = rb_big_clone(z); - zds = BDIGITS(zz); - j = (nx==ny ? nx+2 : nx+1) - ny; - for (i = 0;i < j;i++) zds[i] = zds[i+ny]; - if (!zds[i-1]) i--; - RBIGNUM_SET_LEN(zz, i); + j = nz - ny; + *divp = zz = bignew(j, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y)); + qds = BDIGITS(zz); + for (i = 0;i < j;i++) qds[i] = zds[i+ny]; + if (!qds[i-1]) + RBIGNUM_SET_LEN(zz, i-1); } if (modp) { /* normalize remainder */ - *modp = zz = rb_big_clone(z); - zds = BDIGITS(zz); while (ny > 1 && !zds[ny-1]) --ny; if (dd) { t2 = 0; i = ny; @@ -3866,10 +3864,14 @@ bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp) } } if (!zds[ny-1]) ny--; - RBIGNUM_SET_LEN(zz, ny); - RBIGNUM_SET_SIGN(zz, RBIGNUM_SIGN(x)); + *modp = zz = bignew(ny, RBIGNUM_SIGN(x)); + MEMCPY(BDIGITS(zz), zds, BDIGIT, ny); } - return z; + if (tmpy) + ALLOCV_END(tmpy); + if (tmpz) + ALLOCV_END(tmpz); + return Qnil; } static void -- cgit v1.2.3