Пример #1
0
static VALUE 
bigmul_low_digits(VALUE x, VALUE y, int digits)
{
    int xn = RBIGNUM_LEN(x);
    if (FIXNUM_P(y)) y = INTVALUE2BIG(y);
    int yn = RBIGNUM_LEN(y);

    if (digits > xn + yn) 
    {
        digits = xn + yn;
    }
    VALUE z = rb_big_new(digits, 1);

    BDIGIT* xds = RBIGNUM_DIGITS(x);
    BDIGIT* yds = RBIGNUM_DIGITS(y);
    BDIGIT* zds = RBIGNUM_DIGITS(z);

    BDIGIT c0,c1,c2; // carry
    int i, j, k, beg, end;
    for (k = c0 = c1 = c2 = 0; k < digits; k++)
    {
        beg = k >= yn - 1 ? k - yn + 1 : 0; 
        end = k >= xn     ? xn - 1     : k;
        for (i = beg, j = k - beg; i <= end; ++i, --j)
            MULADD(xds[i], yds[j]);
        zds[k] = c0;
        c0 = c1;
        c1 = c2;
        c2 = 0;
    }
    return rb_big_norm(z);
}
Пример #2
0
static VALUE
bug_big_zero(VALUE self, VALUE length)
{
    long len = NUM2ULONG(length);
    VALUE z = rb_big_new(len, 1);
    MEMZERO(BIGNUM_DIGITS(z), BDIGIT, len);
    return z;
}
Пример #3
0
static VALUE 
bigmul_high_digits(VALUE x, VALUE y, int dontcare, int x_right_shift)
{
    int xn = RBIGNUM_LEN(x);
    if (FIXNUM_P(y)) y = INTVALUE2BIG(y);
    int yn = RBIGNUM_LEN(y);


    BDIGIT* xds = RBIGNUM_DIGITS(x);
    BDIGIT* yds = RBIGNUM_DIGITS(y);

    /* in order to avoid rb_big_clone call,
       let's virtually "shift" x instead of actual shifting */
    if (x_right_shift >= xn) { 
        return INT2BIG(0);
    } else {
        xds += x_right_shift;
        xn -= x_right_shift;
    }

    int digits = xn + yn;
    int i, j, k;
    VALUE z = rb_big_new(digits, 1);
    BDIGIT* zds = RBIGNUM_DIGITS(z);
    for (i = 0; i < digits; zds[i++] = 0);

    int beg, end;

    BDIGIT c0, c1, c2;
    for (k = dontcare, c0 = c1 = c2 = 0; k < digits; k++)
    {
        beg = k >= yn - 1 ? k - yn + 1 : 0; 
        end = k >= xn     ? xn - 1     : k;
        for (i = beg, j = k - beg; i <= end; ++i, --j)
            MULADD(xds[i], yds[j]);
        zds[k] = c0;
        c0 = c1;
        c1 = c2;
        c2 = 0;
    }
    return z;
}