summaryrefslogtreecommitdiff
path: root/bignum.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-11-08 05:29:37 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-11-08 05:29:37 +0000
commitaf328b152b68bb21549e52df230b17a8672795c3 (patch)
tree8a63998435ddc0a3367124967bf063f01e7cfbb9 /bignum.c
parent41e41d34d14ef3595a54148368b89b6c75d0fe4d (diff)
matz
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1031 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r--bignum.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/bignum.c b/bignum.c
index e7f84dc6f9..74cd1507dd 100644
--- a/bignum.c
+++ b/bignum.c
@@ -830,31 +830,39 @@ bigdivrem(x, y, divp, modp)
zds = BDIGITS(z);
if (nx==ny) zds[nx+1] = 0;
while (!yds[ny-1]) ny--;
- if ((dd = BIGRAD/(BDIGIT_DBL_SIGNED)(yds[ny-1]+1)) != 1) {
+
+ dd = 0;
+ q = yds[ny-1];
+ while ((q & (1<<(BITSPERDIG-1))) == 0) {
+ q <<= 1;
+ dd++;
+ }
+ if (dd) {
yy = rb_big_clone(y);
tds = BDIGITS(yy);
j = 0;
- num = 0;
+ t2 = 0;
while (j<ny) {
- num += (BDIGIT_DBL)yds[j]*dd;
- tds[j++] = BIGLO(num);
- num = BIGDN(num);
+ t2 += (BDIGIT_DBL)yds[j]<<dd;
+ tds[j++] = BIGLO(t2);
+ t2 = BIGDN(t2);
}
yds = tds;
j = 0;
- num = 0;
+ t2 = 0;
while (j<nx) {
- num += (BDIGIT_DBL)xds[j]*dd;
- zds[j++] = BIGLO(num);
- num = BIGDN(num);
+ t2 += (BDIGIT_DBL)xds[j]<<dd;
+ zds[j++] = BIGLO(t2);
+ t2 = BIGDN(t2);
}
- zds[j] = (BDIGIT)num;
+ zds[j] = (BDIGIT)t2;
}
else {
zds[nx] = 0;
j = nx;
while (j--) zds[j] = xds[j];
}
+
j = nx==ny?nx+1:nx;
do {
if (zds[j] == yds[ny-1]) q = BIGRAD-1;
@@ -897,9 +905,10 @@ bigdivrem(x, y, divp, modp)
zds = BDIGITS(*modp);
t2 = 0; i = ny;
while(i--) {
- t2 = BIGUP(t2) + zds[i];
- zds[i] = (BDIGIT)(t2 / dd);
- t2 %= dd;
+ t2 = (t2 | zds[i]) >> dd;
+ q = zds[i];
+ zds[i] = BIGLO(t2);
+ t2 = BIGUP(q);
}
}
RBIGNUM(*modp)->len = ny;