summaryrefslogtreecommitdiff
path: root/bignum.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-08-16 01:11:18 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-08-16 01:11:18 +0000
commitdcd4832d6967dab51189382793cb0aadc7705915 (patch)
tree81227a7561b26d1d6c6628e39c76a38630832134 /bignum.c
parent9f6c62ad5f09ec1782442ec499cfd2a9962a3d2c (diff)
* bignum.c (bigdivrem_single1): Renamed from bigdivrem_single. Add
x_higher_bdigit argument. (bigdivrem_single): Just call bigdivrem_single1. (bigdivrem_restoring): Use bigdivrem_single1 to avoid memmove. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42576 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r--bignum.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/bignum.c b/bignum.c
index 92b5b0b773..76f4aa0075 100644
--- a/bignum.c
+++ b/bignum.c
@@ -2677,19 +2677,20 @@ bigdivrem_num_extra_words(size_t xn, size_t yn)
}
static BDIGIT
-bigdivrem_single(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT y)
+bigdivrem_single1(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT x_higher_bdigit, BDIGIT y)
{
assert(0 < xn);
+ assert(x_higher_bdigit < y);
if (POW2_P(y)) {
BDIGIT r;
r = xds[0] & (y-1);
- bary_small_rshift(qds, xds, xn, bitsize(y)-1, 0);
+ bary_small_rshift(qds, xds, xn, bitsize(y)-1, x_higher_bdigit);
return r;
}
else {
size_t i;
BDIGIT_DBL t2;
- t2 = 0;
+ t2 = x_higher_bdigit;
i = xn;
while (i--) {
t2 = BIGUP(t2) + xds[i];
@@ -2700,6 +2701,12 @@ bigdivrem_single(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT y)
}
}
+static BDIGIT
+bigdivrem_single(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT y)
+{
+ return bigdivrem_single1(qds, xds, xn, 0, y);
+}
+
static void
bigdivrem_restoring(BDIGIT *zds, size_t zn, BDIGIT *yds, size_t yn)
{
@@ -2707,15 +2714,14 @@ bigdivrem_restoring(BDIGIT *zds, size_t zn, BDIGIT *yds, size_t yn)
size_t ynzero;
assert(BDIGIT_MSB(yds[yn-1]));
+ assert(zds[zn-1] < yds[yn-1]);
for (ynzero = 0; !yds[ynzero]; ynzero++);
if (ynzero+1 == yn) {
BDIGIT r;
- r = bigdivrem_single(zds+ynzero, zds+ynzero, zn-ynzero, yds[yn-1]);
- assert(zds[zn-1] == 0);
- MEMMOVE(zds+yn, zds+yn-1, BDIGIT, zn - yn);
- zds[yn-1] = r;
+ r = bigdivrem_single1(zds+yn, zds+ynzero, zn-yn, zds[zn-1], yds[ynzero]);
+ zds[ynzero] = r;
return;
}