summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-28 15:14:20 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-28 15:14:20 +0000
commit7a9aeb33dba8d060c60b2bd690172fb7593865d2 (patch)
treef146c48d1297e233cfceead19557ebb8e998c66f
parente4b0852ae46cebab275acb0105332a115e855359 (diff)
* bignum.c (bigdivrem): Specialized implementation added for
nx == 2 && ny == 2 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42218 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--bignum.c21
2 files changed, 26 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 3bc3f680fda..7a011c21c43 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Mon Jul 29 00:11:49 2013 Tanaka Akira <akr@fsij.org>
+
+ * bignum.c (bigdivrem): Specialized implementation added for
+ nx == 2 && ny == 2
+
Sun Jul 28 20:28:41 2013 Masaki Matsushita <glass.saga@gmail.com>
* io.c (io_getpartial): use rb_str_locktmp_ensure().
diff --git a/bignum.c b/bignum.c
index 0c6170ab182..1f3f4b4169d 100644
--- a/bignum.c
+++ b/bignum.c
@@ -5399,6 +5399,27 @@ bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
if (divp) *divp = z;
return Qnil;
}
+ if (nx == 2 && ny == 2) {
+ BDIGIT_DBL x0 = xds[0] | BIGUP(xds[1]);
+ BDIGIT_DBL y0 = yds[0] | BIGUP(yds[1]);
+ BDIGIT_DBL q0 = x0 / y0;
+ BDIGIT_DBL r0 = x0 % y0;
+ if (divp) {
+ z = bignew(bdigit_roomof(sizeof(BDIGIT_DBL)), RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
+ zds = BDIGITS(z);
+ zds[0] = BIGLO(q0);
+ zds[1] = BIGLO(BIGDN(q0));
+ *divp = z;
+ }
+ if (modp) {
+ z = bignew(bdigit_roomof(sizeof(BDIGIT_DBL)), RBIGNUM_SIGN(x));
+ zds = BDIGITS(z);
+ zds[0] = BIGLO(r0);
+ zds[1] = BIGLO(BIGDN(r0));
+ *modp = z;
+ }
+ return Qnil;
+ }
if (BDIGIT_MSB(yds[ny-1]) == 0) {
/* Make yds modifiable. */