From ca3f5b533d7bd8027a729d068e843a01a8990ee4 Mon Sep 17 00:00:00 2001 From: akr Date: Tue, 23 Jul 2013 11:16:39 +0000 Subject: * bignum.c (bary_divmod): Add special cases for x < y easily detected and nx == 2 && ny == 2. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42139 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ bignum.c | 19 ++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 326604c94e..a37eabd251 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Tue Jul 23 20:14:55 2013 Tanaka Akira + + * bignum.c (bary_divmod): Add special cases for x < y easily detected + and nx == 2 && ny == 2. + Tue Jul 23 19:48:38 2013 Koichi Sasada * thread_(pthread|win32).h: rename rb_thread_cond_t to diff --git a/bignum.c b/bignum.c index 820be62158..e1d7a6d871 100644 --- a/bignum.c +++ b/bignum.c @@ -5266,12 +5266,29 @@ bary_divmod(BDIGIT *qds, size_t nq, BDIGIT *rds, size_t nr, BDIGIT *xds, size_t return; } - if (ny == 1) { + if (nx < ny || (nx == ny && xds[nx - 1] < yds[ny - 1])) { + MEMCPY(rds, xds, BDIGIT, nx); + BDIGITS_ZERO(rds+nx, nr-nx); + BDIGITS_ZERO(qds, nq); + } + else if (ny == 1) { MEMCPY(qds, xds, BDIGIT, nx); BDIGITS_ZERO(qds+nx, nq-nx); rds[0] = bigdivrem_single(qds, xds, nx, yds[0]); BDIGITS_ZERO(rds+1, nr-1); } + else if (nx == 2 && ny == 2) { + BDIGIT_DBL x = xds[0] | BIGUP(xds[1]); + BDIGIT_DBL y = yds[0] | BIGUP(yds[1]); + BDIGIT_DBL q = x / y; + BDIGIT_DBL r = x % y; + qds[0] = BIGLO(q); + qds[1] = BIGLO(BIGDN(q)); + BDIGITS_ZERO(qds+2, nq-2); + rds[0] = BIGLO(r); + rds[1] = BIGLO(BIGDN(r)); + BDIGITS_ZERO(rds+2, nr-2); + } else { int extra_words; long j; -- cgit v1.2.3