summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;