示例#1
0
// Returns a / b.
Integer Integer::divide(Integer& a, Integer& b) const
{
    Integer q, row;
    int asign = a.sign();
    int bsign = b.sign();
    int i;
    q.set_size(a.size());
    a.set_sign(PLUS);
    b.set_sign(PLUS);

    for (i = a.size() - 1; i >= 0; i--) {
        row <<= 1;
        row[0] = a[i];
        q[i] = 0;

        while (row >= b) {
            q[i]++;
            row -= b;
        }
    }

    q.adjust();

    if (q == ZERO)
        q.set_sign(PLUS);
    else
        q.set_sign(asign * bsign);

    a.set_sign(asign);
    b.set_sign(bsign);

    return q;
}
示例#2
0
// Return a * b. This method is known as "Long Multiplication".
// Complexity: O(n^2)
Integer Integer::multiply(Integer& a, Integer& b) const
{
    Integer ans;
    unsigned int i, j, k, n, carry_mult, carry_sum;

    for (i = 0; i < a.size(); i++) {
        carry_mult = carry_sum = 0;
        k = i; // Shifting

        for (j = 0; j < b.size(); j++) {
            n = a[i] * b[j] + carry_mult;
            carry_mult = n / BASE;

            n = ans[k] + n % BASE + carry_sum;
            carry_sum = n / BASE;

            ans[k] = n % BASE;
            k++;
        }

        if (carry_sum > 0 || carry_mult > 0) {
            ans[k++] = carry_sum + carry_mult;
        }

        ans.set_size(k);
    }

    if (ans == ZERO)
        ans.set_sign(PLUS);
    else
        ans.set_sign(a.sign() * b.sign());

    return ans;
}
示例#3
0
//  Compare a with b, possible results are:
//  0         : a and b are equals.
//  PLUS(1)   : b > a
//  MINUS(-1) : b < a
int Integer::compare(const Integer& a, const Integer& b) const
{
    if (a.sign() == MINUS && b.sign() == PLUS) {
        return PLUS;
    }

    if (a.sign() == PLUS && b.sign() == MINUS) {
        return MINUS;
    }

    if (b.size() > a.size()) {
        return PLUS * a.sign();
    }

    if (a.size() > b.size()) {
        return MINUS * a.sign();
    }

    for (int i = a.size() - 1; i >= 0; i--) {
        if (a[i] > b[i]) {
            return MINUS * a.sign();
        }

        if (b[i] > a[i]) {
            return PLUS * a.sign();
        }
    }

    return 0;
}
示例#4
0
// a and b are positive integers.
Integer Integer::subtract(Integer& a, Integer& b) const
{
    Integer ans;
    int borrow = 0, n;

    // Three special cases:
    //  a - (-b) ==  a + b
    // -a - b    == -a + (-b)
    // -a - (-b) == -a + b
    if (a.sign() == MINUS || b.sign() == MINUS) {  
        b.set_sign(MINUS * b.sign());
        ans = add(a, b);
        b.set_sign(MINUS * b.sign());
        return ans;
    }

    if (a == b) {
        return ZERO;
    }

    if (a < b) {
        ans = subtract(b, a);
        ans.set_sign(MINUS);
        return ans;
    }

    unsigned int i;

    for (i = 0; i < a.size(); i++) {
        n = a[i] - b[i] - borrow;
        borrow = (n < 0) ? 1 : 0;

        if (n < 0) {
            n += BASE;
        }

        ans[i] = n;
    }

    ans.set_size(i);
    ans.adjust();
    ans.set_sign(PLUS);

    return ans;
}
示例#5
0
// Returns a new integer c = a + b
Integer Integer::add(Integer &a, Integer &b) const
{
    Integer c;
    int carry = 0, i;

    if (a.sign() == b.sign()) {
        c.set_sign(a.sign());
    } else {
        if (a.sign() == MINUS) {
            a.set_sign(PLUS);
            c = subtract(b, a);
            a.set_sign(MINUS);
        } else {
            b.set_sign(PLUS);
            c = subtract(a, b);
            b.set_sign(MINUS);
        }

        return c;
    }

    int max = std::max(a.size(), b.size());
    int n;

    for (i = 0; i < max; i++) {
        n = carry + a[i] + b[i];
        c[i] = n % BASE;
        carry = n / BASE;
    }

    if (carry > 0) {
        c[i++] = carry;
    }

    c.set_size(i);
    c.adjust();
    return c;
}
示例#6
0
// Returns the absolute value of (*this).
Integer Integer::abs() const
{
    Integer temp = *this;
    temp.set_sign(temp.sign() * temp.sign());
    return temp;
}
示例#7
0
Decimal Type::createDecimal( const Integer& value )
{
    assert( value.trivial() );
    Decimal tmp( value.value(), value.sign() );
    return tmp;
}