mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* bignum.c (rb_str2big_poweroftwo): New function.
(rb_str2big_normal): Ditto. (rb_str2big_karatsuba): Ditto. * internal.h (rb_str2big_poweroftwo): Declared. (rb_str2big_normal): Ditto. (rb_str2big_karatsuba): Ditto. * ext/-test-/bignum/str2big.c: New file. * test/-ext-/bignum/test_str2big.rb: New file. * ext/-test-/bignum/depend: Add the dependency for str2big.c. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42797 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
1df73dd9ad
commit
0b2413b471
6 changed files with 189 additions and 0 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
||||||
|
Tue Sep 3 12:45:23 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* bignum.c (rb_str2big_poweroftwo): New function.
|
||||||
|
(rb_str2big_normal): Ditto.
|
||||||
|
(rb_str2big_karatsuba): Ditto.
|
||||||
|
|
||||||
|
* internal.h (rb_str2big_poweroftwo): Declared.
|
||||||
|
(rb_str2big_normal): Ditto.
|
||||||
|
(rb_str2big_karatsuba): Ditto.
|
||||||
|
|
||||||
|
* ext/-test-/bignum/str2big.c: New file.
|
||||||
|
|
||||||
|
* test/-ext-/bignum/test_str2big.rb: New file.
|
||||||
|
|
||||||
|
* ext/-test-/bignum/depend: Add the dependency for str2big.c.
|
||||||
|
|
||||||
Tue Sep 3 12:09:08 2013 Tanaka Akira <akr@fsij.org>
|
Tue Sep 3 12:09:08 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* process.c (rb_clock_gettime): Support times() based monotonic clock.
|
* process.c (rb_clock_gettime): Support times() based monotonic clock.
|
||||||
|
|
111
bignum.c
111
bignum.c
|
@ -3972,6 +3972,117 @@ rb_str_to_inum(VALUE str, int base, int badcheck)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_str2big_poweroftwo(VALUE arg, int base, int badcheck)
|
||||||
|
{
|
||||||
|
int positive_p = 1;
|
||||||
|
const char *s, *str;
|
||||||
|
const char *digits_start, *digits_end;
|
||||||
|
size_t num_digits;
|
||||||
|
size_t len;
|
||||||
|
VALUE z;
|
||||||
|
|
||||||
|
if (base < 2 || 36 < base || !POW2_P(base)) {
|
||||||
|
rb_raise(rb_eArgError, "invalid radix %d", base);
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_must_asciicompat(arg);
|
||||||
|
s = str = StringValueCStr(arg);
|
||||||
|
if (*str == '-') {
|
||||||
|
str++;
|
||||||
|
positive_p = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
digits_start = str;
|
||||||
|
str2big_scan_digits(s, str, base, badcheck, &num_digits, &len);
|
||||||
|
digits_end = digits_start + len;
|
||||||
|
|
||||||
|
z = str2big_poweroftwo(positive_p, digits_start, digits_end, num_digits,
|
||||||
|
bit_length(base-1));
|
||||||
|
|
||||||
|
RB_GC_GUARD(arg);
|
||||||
|
|
||||||
|
return bignorm(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_str2big_normal(VALUE arg, int base, int badcheck)
|
||||||
|
{
|
||||||
|
int positive_p = 1;
|
||||||
|
const char *s, *str;
|
||||||
|
const char *digits_start, *digits_end;
|
||||||
|
size_t num_digits;
|
||||||
|
size_t len;
|
||||||
|
VALUE z;
|
||||||
|
|
||||||
|
int digits_per_bdigits_dbl;
|
||||||
|
size_t num_bdigits;
|
||||||
|
|
||||||
|
if (base < 2 || 36 < base) {
|
||||||
|
rb_raise(rb_eArgError, "invalid radix %d", base);
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_must_asciicompat(arg);
|
||||||
|
s = str = StringValueCStr(arg);
|
||||||
|
if (*str == '-') {
|
||||||
|
str++;
|
||||||
|
positive_p = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
digits_start = str;
|
||||||
|
str2big_scan_digits(s, str, base, badcheck, &num_digits, &len);
|
||||||
|
digits_end = digits_start + len;
|
||||||
|
|
||||||
|
maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
|
||||||
|
num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
|
||||||
|
|
||||||
|
z = str2big_normal(positive_p, digits_start, digits_end,
|
||||||
|
num_bdigits, base);
|
||||||
|
|
||||||
|
RB_GC_GUARD(arg);
|
||||||
|
|
||||||
|
return bignorm(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_str2big_karatsuba(VALUE arg, int base, int badcheck)
|
||||||
|
{
|
||||||
|
int positive_p = 1;
|
||||||
|
const char *s, *str;
|
||||||
|
const char *digits_start, *digits_end;
|
||||||
|
size_t num_digits;
|
||||||
|
size_t len;
|
||||||
|
VALUE z;
|
||||||
|
|
||||||
|
int digits_per_bdigits_dbl;
|
||||||
|
size_t num_bdigits;
|
||||||
|
|
||||||
|
if (base < 2 || 36 < base) {
|
||||||
|
rb_raise(rb_eArgError, "invalid radix %d", base);
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_must_asciicompat(arg);
|
||||||
|
s = str = StringValueCStr(arg);
|
||||||
|
if (*str == '-') {
|
||||||
|
str++;
|
||||||
|
positive_p = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
digits_start = str;
|
||||||
|
str2big_scan_digits(s, str, base, badcheck, &num_digits, &len);
|
||||||
|
digits_end = digits_start + len;
|
||||||
|
|
||||||
|
maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
|
||||||
|
num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
|
||||||
|
|
||||||
|
z = str2big_karatsuba(positive_p, digits_start, digits_end, num_digits,
|
||||||
|
num_bdigits, digits_per_bdigits_dbl, base);
|
||||||
|
|
||||||
|
RB_GC_GUARD(arg);
|
||||||
|
|
||||||
|
return bignorm(z);
|
||||||
|
}
|
||||||
|
|
||||||
#if HAVE_LONG_LONG
|
#if HAVE_LONG_LONG
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
|
|
@ -3,3 +3,4 @@ $(OBJS): $(HDRS) $(ruby_headers)
|
||||||
intpack.o: intpack.c $(top_srcdir)/internal.h
|
intpack.o: intpack.c $(top_srcdir)/internal.h
|
||||||
mul.o: mul.c $(top_srcdir)/internal.h
|
mul.o: mul.c $(top_srcdir)/internal.h
|
||||||
big2str.o: big2str.c $(top_srcdir)/internal.h
|
big2str.o: big2str.c $(top_srcdir)/internal.h
|
||||||
|
str2big.o: big2str.c $(top_srcdir)/internal.h
|
||||||
|
|
28
ext/-test-/bignum/str2big.c
Normal file
28
ext/-test-/bignum/str2big.c
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#include "ruby.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
str2big_poweroftwo(VALUE str, VALUE vbase, VALUE badcheck)
|
||||||
|
{
|
||||||
|
return rb_str2big_poweroftwo(str, NUM2INT(vbase), RTEST(badcheck));
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
str2big_normal(VALUE str, VALUE vbase, VALUE badcheck)
|
||||||
|
{
|
||||||
|
return rb_str2big_normal(str, NUM2INT(vbase), RTEST(badcheck));
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
str2big_karatsuba(VALUE str, VALUE vbase, VALUE badcheck)
|
||||||
|
{
|
||||||
|
return rb_str2big_karatsuba(str, NUM2INT(vbase), RTEST(badcheck));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Init_str2big(VALUE klass)
|
||||||
|
{
|
||||||
|
rb_define_method(rb_cString, "str2big_poweroftwo", str2big_poweroftwo, 2);
|
||||||
|
rb_define_method(rb_cString, "str2big_normal", str2big_normal, 2);
|
||||||
|
rb_define_method(rb_cString, "str2big_karatsuba", str2big_karatsuba, 2);
|
||||||
|
}
|
|
@ -647,6 +647,9 @@ VALUE rb_big_mul_toom3(VALUE x, VALUE y);
|
||||||
VALUE rb_big_sq_fast(VALUE x);
|
VALUE rb_big_sq_fast(VALUE x);
|
||||||
VALUE rb_big2str_poweroftwo(VALUE x, int base);
|
VALUE rb_big2str_poweroftwo(VALUE x, int base);
|
||||||
VALUE rb_big2str_generic(VALUE x, int base);
|
VALUE rb_big2str_generic(VALUE x, int base);
|
||||||
|
VALUE rb_str2big_poweroftwo(VALUE arg, int base, int badcheck);
|
||||||
|
VALUE rb_str2big_normal(VALUE arg, int base, int badcheck);
|
||||||
|
VALUE rb_str2big_karatsuba(VALUE arg, int base, int badcheck);
|
||||||
#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
|
#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
|
||||||
VALUE rb_big_mul_gmp(VALUE x, VALUE y);
|
VALUE rb_big_mul_gmp(VALUE x, VALUE y);
|
||||||
VALUE rb_big2str_gmp(VALUE x, int base);
|
VALUE rb_big2str_gmp(VALUE x, int base);
|
||||||
|
|
30
test/-ext-/bignum/test_str2big.rb
Normal file
30
test/-ext-/bignum/test_str2big.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
require 'test/unit'
|
||||||
|
require "-test-/bignum"
|
||||||
|
|
||||||
|
class TestBignum < Test::Unit::TestCase
|
||||||
|
class TestStr2big < Test::Unit::TestCase
|
||||||
|
|
||||||
|
SIZEOF_BDIGITS = Bignum::SIZEOF_BDIGITS
|
||||||
|
BITSPERDIG = Bignum::BITSPERDIG
|
||||||
|
BDIGMAX = (1 << BITSPERDIG) - 1
|
||||||
|
|
||||||
|
def test_str2big_poweroftwo
|
||||||
|
s = "1" + "0" * 1000
|
||||||
|
n = 16 ** 1000
|
||||||
|
assert_equal(n, s.str2big_poweroftwo(16, true))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_str2big_normal
|
||||||
|
s = "1" + "0" * 1000
|
||||||
|
n = 10 ** 1000
|
||||||
|
assert_equal(n, s.str2big_normal(10, true))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_str2big_karatsuba
|
||||||
|
s = "1" + "0" * 1000
|
||||||
|
n = 10 ** 1000
|
||||||
|
assert_equal(n, s.str2big_karatsuba(10, true))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Reference in a new issue