summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-23 11:16:39 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-23 11:16:39 +0000
commitca3f5b533d7bd8027a729d068e843a01a8990ee4 (patch)
tree0d78db9ccfe00a39bd6e83f8a7d66f5d28ef25a8
parent4d3feac974f7b854c809f32541a30fa1be817540 (diff)
* 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
-rw-r--r--ChangeLog5
-rw-r--r--bignum.c19
2 files changed, 23 insertions, 1 deletions
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 <akr@fsij.org>
+
+ * 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 <ko1@atdot.net>
* 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;