mruby-bigint/bigint.c (udiv): skip loop if xd<yd.

This commit is contained in:
Yukihiro "Matz" Matsumoto
2022-10-28 16:59:09 +09:00
parent 02f44d76fc
commit 5ccca7e45b
+26 -24
View File
@@ -459,34 +459,36 @@ udiv(mrb_state *mrb, mpz_t *qq, mpz_t *rr, mpz_t *xx, mpz_t *yy)
size_t xd = digits(&x);
mpz_realloc(mrb, &q, xd);
mp_dbl_limb z = y.p[yd-1];
for (size_t j=xd-yd;; j--) {
mp_dbl_limb_signed b=0;
mp_dbl_limb qhat;
if (xd>=yd) {
for (size_t j=xd-yd;; j--) {
mp_dbl_limb_signed b=0;
mp_dbl_limb qhat;
if (j+yd == xd)
qhat = x.p[j+yd-1] / z;
else
qhat = (((mp_dbl_limb)x.p[j+yd] << DIG_SIZE) + x.p[j+yd-1]) / z;
if (qhat) {
for (i=0; i<yd; i++) {
mp_dbl_limb zz = qhat * y.p[i];
mp_dbl_limb_signed u = LOW(b)+x.p[i+j]-LOW(zz);
x.p[i+j] = LOW(u);
b = HIGH(b) - HIGH(zz) + HIGH(u);
if (j+yd == xd)
qhat = x.p[j+yd-1] / z;
else
qhat = (((mp_dbl_limb)x.p[j+yd] << DIG_SIZE) + x.p[j+yd-1]) / z;
if (qhat) {
for (i=0; i<yd; i++) {
mp_dbl_limb zz = qhat * y.p[i];
mp_dbl_limb_signed u = LOW(b)+x.p[i+j]-LOW(zz);
x.p[i+j] = LOW(u);
b = HIGH(b) - HIGH(zz) + HIGH(u);
}
b += x.p[i+j];
}
b += x.p[i+j];
}
for (; b!=0; qhat--) {
mp_dbl_limb c = 0;
for (i=0; i<yd; i++) {
c += (mp_dbl_limb)x.p[i+j] + (mp_dbl_limb)y.p[i];
x.p[i+j] = LOW(c);
c = HIGH(c);
for (; b!=0; qhat--) {
mp_dbl_limb c = 0;
for (i=0; i<yd; i++) {
c += (mp_dbl_limb)x.p[i+j] + (mp_dbl_limb)y.p[i];
x.p[i+j] = LOW(c);
c = HIGH(c);
}
b += c;
}
b += c;
q.p[j] = (mp_limb)qhat;
if (j == 0) break;
}
q.p[j] = (mp_limb)qhat;
if (j == 0) break;
}
x.sz = yy->sz;
urshift(mrb, rr, &x, ns);