Esempio n. 1
0
RCP<const UnivariateIntPolynomial> mul_poly(const UnivariateIntPolynomial &a,
                                            const UnivariateIntPolynomial &b)
{
    RCP<const Symbol> var = symbol("");
    if (a.get_var()->get_name() == "") {
        var = b.get_var();
    } else if (b.get_var()->get_name() == "") {
        var = a.get_var();
    } else if (!(a.get_var()->__eq__(*b.get_var()))) {
        throw std::runtime_error("Error: variables must agree.");
    } else {
        var = a.get_var();
    }

    bool neg = false;

    if ((--(a.get_dict().end()))->second < 0)
        neg = not neg;
    if ((--(b.get_dict().end()))->second < 0)
        neg = not neg;

    unsigned int N
        = bit_length(std::min(a.get_degree() + 1, b.get_degree() + 1))
          + bit_length(a.max_abs_coef()) + bit_length(b.max_abs_coef());

    integer_class a1(1), b1;
    a1 <<= N;
    integer_class a2 = a1 / 2;
    integer_class mask = a1 - 1;
    integer_class a_val(a.eval_bit(N)), b_val(b.eval_bit(N));
    integer_class s_val(a_val * b_val);
    integer_class r = mp_abs(s_val);

    std::vector<integer_class> v;
    integer_class carry(0);

    while (r != 0 or carry != 0) {
        mp_and(b1, r, mask);
        if (b1 < a2) {
            v.push_back(b1 + carry);
            carry = 0;
        } else {
            v.push_back(b1 - a1 + carry);
            carry = 1;
        }
        r >>= N;
    }
    if (neg)
        return neg_poly(*UnivariateIntPolynomial::from_vec(var, v));
    else
        return UnivariateIntPolynomial::from_vec(var, v);
}
Esempio n. 2
0
/* two complement and */
int mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c)
{
   int res = MP_OKAY, bits, abits, bbits;
   int sa = a->sign, sb = b->sign;
   mp_int *mx = NULL, _mx, acpy, bcpy;

   if ((sa == MP_NEG) || (sb == MP_NEG)) {
      abits = mp_count_bits(a);
      bbits = mp_count_bits(b);
      bits = MP_MAX(abits, bbits);
      res = mp_init_set_int(&_mx, 1uL);
      if (res != MP_OKAY) {
         goto end;
      }

      mx = &_mx;
      res = mp_mul_2d(mx, bits + 1, mx);
      if (res != MP_OKAY) {
         goto end;
      }

      if (sa == MP_NEG) {
         res = mp_init(&acpy);
         if (res != MP_OKAY) {
            goto end;
         }

         res = mp_add(mx, a, &acpy);
         if (res != MP_OKAY) {
            mp_clear(&acpy);
            goto end;
         }
         a = &acpy;
      }
      if (sb == MP_NEG) {
         res = mp_init(&bcpy);
         if (res != MP_OKAY) {
            goto end;
         }

         res = mp_add(mx, b, &bcpy);
         if (res != MP_OKAY) {
            mp_clear(&bcpy);
            goto end;
         }
         b = &bcpy;
      }
   }

   res = mp_and(a, b, c);

   if ((sa == MP_NEG) && (sb == MP_NEG) && (res == MP_OKAY)) {
      res = mp_sub(c, mx, c);
   }

end:
   if (a == &acpy) {
      mp_clear(&acpy);
   }

   if (b == &bcpy) {
      mp_clear(&bcpy);
   }

   if (mx == &_mx) {
      mp_clear(mx);
   }

   return res;
}