T AP_div(T x, T y) { T q, r; assert(x); assert(y); assert(!iszero(y)); q = mk(x->ndigits); r = mk(y->ndigits); { XP_T tmp = ALLOC(x->ndigits + y->ndigits + 2); XP_div(x->ndigits, q->digits, x->digits, y->ndigits, y->digits, r->digits, tmp); FREE(tmp); } normalize(q, q->size); normalize(r, r->size); q->sign = iszero(q) || ((x->sign^y->sign) == 0) ? 1 : -1; if (!((x->sign^y->sign) == 0) && !iszero(r)) { int carry = XP_sum(q->size, q->digits, q->digits, 1); assert(carry == 0); normalize(q, q->size); } AP_free(&r); return q; }
T MP_addui(T z, T x, unsigned long y) { assert(x); assert(z); if (y < BASE) { int carry = XP_sum(nbytes, z, x, y); carry |= z[nbytes-1]&~msb; z[nbytes-1] &= msb; if (carry) RAISE(MP_Overflow); } else if (applyu(MP_addu, z, x, y)) RAISE(MP_Overflow); return z; }
static T add(T z, T x, T y) { int n = y->ndigits; if (x->ndigits < n) return add(z, y, x); else if (x->ndigits > n) { int carry = XP_add(n, z->digits, x->digits, y->digits, 0); z->digits[z->size-1] = XP_sum(x->ndigits - n, &z->digits[n], &x->digits[n], carry); } else z->digits[n] = XP_add(n, z->digits, x->digits, y->digits, 0); return normalize(z, z->size); }
T MP_subi(T z, T x, long y) { assert(x); assert(z); if (-BASE < y && y < BASE) { int sx = sign(x), sy = y < 0; if (sy) XP_sum (nbytes, z, x, -y); else XP_diff(nbytes, z, x, y); z[nbytes-1] &= msb; if (sx != sy && sy == sign(z)) RAISE(MP_Overflow); if (nbits < 8 && (y < -(1<<(nbits-1)) || y >= (1<<(nbits-1)))) RAISE(MP_Overflow); } else if (apply(MP_sub, z, x, y)) RAISE(MP_Overflow); return z; }