mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* bignum.c (rb_big_sq_fast): New function for testing.
(rb_big_mul_toom3): Ditto. * internal.h (rb_big_sq_fast): Declared. (rb_big_mul_toom3): Ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41832 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
85855a2242
commit
6fdad008a2
5 changed files with 68 additions and 3 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
Mon Jul 8 22:03:30 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* bignum.c (rb_big_sq_fast): New function for testing.
|
||||||
|
(rb_big_mul_toom3): Ditto.
|
||||||
|
|
||||||
|
* internal.h (rb_big_sq_fast): Declared.
|
||||||
|
(rb_big_mul_toom3): Ditto.
|
||||||
|
|
||||||
Mon Jul 8 21:59:34 2013 Tanaka Akira <akr@fsij.org>
|
Mon Jul 8 21:59:34 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* bignum.c (bary_mul_balance): Initialize a local variable to suppress
|
* bignum.c (bary_mul_balance): Initialize a local variable to suppress
|
||||||
|
|
25
bignum.c
25
bignum.c
|
@ -1515,7 +1515,8 @@ bary_sq_fast(BDIGIT *zds, size_t zn, BDIGIT *xds, size_t xn)
|
||||||
MEMZERO(zds, BDIGIT, zn);
|
MEMZERO(zds, BDIGIT, zn);
|
||||||
for (i = 0; i < xn; i++) {
|
for (i = 0; i < xn; i++) {
|
||||||
v = (BDIGIT_DBL)xds[i];
|
v = (BDIGIT_DBL)xds[i];
|
||||||
if (!v) continue;
|
if (!v)
|
||||||
|
continue;
|
||||||
c = (BDIGIT_DBL)zds[i + i] + v * v;
|
c = (BDIGIT_DBL)zds[i + i] + v * v;
|
||||||
zds[i + i] = BIGLO(c);
|
zds[i + i] = BIGLO(c);
|
||||||
c = BIGDN(c);
|
c = BIGDN(c);
|
||||||
|
@ -1525,18 +1526,30 @@ bary_sq_fast(BDIGIT *zds, size_t zn, BDIGIT *xds, size_t xn)
|
||||||
c += (BDIGIT_DBL)zds[i + j] + BIGLO(v) * w;
|
c += (BDIGIT_DBL)zds[i + j] + BIGLO(v) * w;
|
||||||
zds[i + j] = BIGLO(c);
|
zds[i + j] = BIGLO(c);
|
||||||
c = BIGDN(c);
|
c = BIGDN(c);
|
||||||
if (BIGDN(v)) c += w;
|
if (BIGDN(v))
|
||||||
|
c += w;
|
||||||
}
|
}
|
||||||
if (c) {
|
if (c) {
|
||||||
c += (BDIGIT_DBL)zds[i + xn];
|
c += (BDIGIT_DBL)zds[i + xn];
|
||||||
zds[i + xn] = BIGLO(c);
|
zds[i + xn] = BIGLO(c);
|
||||||
c = BIGDN(c);
|
c = BIGDN(c);
|
||||||
assert(c == 0 || i != xn-1);
|
assert(c == 0 || i != xn-1);
|
||||||
if (c && i != xn-1) zds[i + xn + 1] += (BDIGIT)c;
|
if (c && i != xn-1)
|
||||||
|
zds[i + xn + 1] += (BDIGIT)c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_big_sq_fast(VALUE x)
|
||||||
|
{
|
||||||
|
size_t xn = RBIGNUM_LEN(x), zn = 2 * xn;
|
||||||
|
VALUE z = bignew(zn, 1);
|
||||||
|
bary_sq_fast(BDIGITS(z), zn, BDIGITS(x), xn);
|
||||||
|
RB_GC_GUARD(x);
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
/* balancing multiplication by slicing larger argument */
|
/* balancing multiplication by slicing larger argument */
|
||||||
static void
|
static void
|
||||||
bary_mul_balance(BDIGIT *zds, size_t zl, BDIGIT *xds, size_t xl, BDIGIT *yds, size_t yl)
|
bary_mul_balance(BDIGIT *zds, size_t zl, BDIGIT *xds, size_t xl, BDIGIT *yds, size_t yl)
|
||||||
|
@ -4626,6 +4639,12 @@ bigmul1_toom3(VALUE x, VALUE y)
|
||||||
return bignorm(z);
|
return bignorm(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_big_mul_toom3(VALUE x, VALUE y)
|
||||||
|
{
|
||||||
|
return bigmul1_toom3(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
bigmul0(VALUE x, VALUE y)
|
bigmul0(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,12 @@ mul_normal(VALUE x, VALUE y)
|
||||||
return rb_big_norm(rb_big_mul_normal(big(x), big(y)));
|
return rb_big_norm(rb_big_mul_normal(big(x), big(y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
sq_fast(VALUE x)
|
||||||
|
{
|
||||||
|
return rb_big_norm(rb_big_sq_fast(big(x)));
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
mul_balance(VALUE x, VALUE y)
|
mul_balance(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
|
@ -30,12 +36,20 @@ mul_karatsuba(VALUE x, VALUE y)
|
||||||
return rb_big_norm(rb_big_mul_karatsuba(big(x), big(y)));
|
return rb_big_norm(rb_big_mul_karatsuba(big(x), big(y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
mul_toom3(VALUE x, VALUE y)
|
||||||
|
{
|
||||||
|
return rb_big_norm(rb_big_mul_toom3(big(x), big(y)));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Init_mul(VALUE klass)
|
Init_mul(VALUE klass)
|
||||||
{
|
{
|
||||||
rb_define_const(rb_cBignum, "SIZEOF_BDIGITS", INT2NUM(SIZEOF_BDIGITS));
|
rb_define_const(rb_cBignum, "SIZEOF_BDIGITS", INT2NUM(SIZEOF_BDIGITS));
|
||||||
rb_define_const(rb_cBignum, "BITSPERDIG", INT2NUM(SIZEOF_BDIGITS * CHAR_BIT));
|
rb_define_const(rb_cBignum, "BITSPERDIG", INT2NUM(SIZEOF_BDIGITS * CHAR_BIT));
|
||||||
rb_define_method(rb_cInteger, "big_mul_normal", mul_normal, 1);
|
rb_define_method(rb_cInteger, "big_mul_normal", mul_normal, 1);
|
||||||
|
rb_define_method(rb_cInteger, "big_sq_fast", sq_fast, 0);
|
||||||
rb_define_method(rb_cInteger, "big_mul_balance", mul_balance, 1);
|
rb_define_method(rb_cInteger, "big_mul_balance", mul_balance, 1);
|
||||||
rb_define_method(rb_cInteger, "big_mul_karatsuba", mul_karatsuba, 1);
|
rb_define_method(rb_cInteger, "big_mul_karatsuba", mul_karatsuba, 1);
|
||||||
|
rb_define_method(rb_cInteger, "big_mul_toom3", mul_toom3, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -518,6 +518,8 @@ VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, siz
|
||||||
VALUE rb_big_mul_normal(VALUE x, VALUE y);
|
VALUE rb_big_mul_normal(VALUE x, VALUE y);
|
||||||
VALUE rb_big_mul_balance(VALUE x, VALUE y);
|
VALUE rb_big_mul_balance(VALUE x, VALUE y);
|
||||||
VALUE rb_big_mul_karatsuba(VALUE x, VALUE y);
|
VALUE rb_big_mul_karatsuba(VALUE x, VALUE y);
|
||||||
|
VALUE rb_big_mul_toom3(VALUE x, VALUE y);
|
||||||
|
VALUE rb_big_sq_fast(VALUE x);
|
||||||
|
|
||||||
/* io.c */
|
/* io.c */
|
||||||
void rb_maygvl_fd_fix_cloexec(int fd);
|
void rb_maygvl_fd_fix_cloexec(int fd);
|
||||||
|
|
|
@ -36,6 +36,22 @@ class TestBignum < Test::Unit::TestCase
|
||||||
assert_equal(z, x.big_mul_normal(y))
|
assert_equal(z, x.big_mul_normal(y))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_sq_fast
|
||||||
|
x = (1 << BITSPERDIG) | 1
|
||||||
|
z = (1 << 2*BITSPERDIG) | (2 << BITSPERDIG) | 1
|
||||||
|
assert_equal(z, x.big_sq_fast)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_sq_fast_max2
|
||||||
|
x = (BDIGMAX << BITSPERDIG) | BDIGMAX
|
||||||
|
assert_equal(x.big_mul_normal(x), x.big_sq_fast)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_sq_fast_zero_in_middle
|
||||||
|
x = (BDIGMAX << 2*BITSPERDIG) | BDIGMAX
|
||||||
|
assert_equal(x.big_mul_normal(x), x.big_sq_fast)
|
||||||
|
end
|
||||||
|
|
||||||
def test_mul_balance
|
def test_mul_balance
|
||||||
x = (1 << BITSPERDIG) | 1
|
x = (1 << BITSPERDIG) | 1
|
||||||
y = (1 << BITSPERDIG) | 1
|
y = (1 << BITSPERDIG) | 1
|
||||||
|
@ -104,5 +120,11 @@ class TestBignum < Test::Unit::TestCase
|
||||||
assert_equal(x.big_mul_normal(y), x.big_mul_karatsuba(y))
|
assert_equal(x.big_mul_normal(y), x.big_mul_karatsuba(y))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_mul_toom3
|
||||||
|
x = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1
|
||||||
|
y = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1
|
||||||
|
assert_equal(x.big_mul_normal(y), x.big_mul_toom3(y))
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue