[前][次][番号順一覧][スレッド一覧]

ruby-changes:30718

From: akr <ko1@a...>
Date: Tue, 3 Sep 2013 12:50:24 +0900 (JST)
Subject: [ruby-changes:30718] akr:r42797 (trunk): * bignum.c (rb_str2big_poweroftwo): New function.

akr	2013-09-03 12:50:15 +0900 (Tue, 03 Sep 2013)

  New Revision: 42797

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=42797

  Log:
    * 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.

  Added files:
    trunk/ext/-test-/bignum/str2big.c
    trunk/test/-ext-/bignum/test_str2big.rb
  Modified files:
    trunk/ChangeLog
    trunk/bignum.c
    trunk/ext/-test-/bignum/depend
    trunk/internal.h
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 42796)
+++ ChangeLog	(revision 42797)
@@ -1,3 +1,19 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Sep  3 12:45:23 2013  Tanaka Akira  <akr@f...>
+
+	* 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@f...>
 
 	* process.c (rb_clock_gettime): Support times() based monotonic clock.
Index: ext/-test-/bignum/depend
===================================================================
--- ext/-test-/bignum/depend	(revision 42796)
+++ ext/-test-/bignum/depend	(revision 42797)
@@ -3,3 +3,4 @@ $(OBJS): $(HDRS) $(ruby_headers) https://github.com/ruby/ruby/blob/trunk/ext/-test-/bignum/depend#L3
 intpack.o: intpack.c $(top_srcdir)/internal.h
 mul.o: mul.c $(top_srcdir)/internal.h
 big2str.o: big2str.c $(top_srcdir)/internal.h
+str2big.o: big2str.c $(top_srcdir)/internal.h
Index: ext/-test-/bignum/str2big.c
===================================================================
--- ext/-test-/bignum/str2big.c	(revision 0)
+++ ext/-test-/bignum/str2big.c	(revision 42797)
@@ -0,0 +1,28 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/bignum/str2big.c#L1
+#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);
+}
Index: internal.h
===================================================================
--- internal.h	(revision 42796)
+++ internal.h	(revision 42797)
@@ -647,6 +647,9 @@ VALUE rb_big_mul_toom3(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/internal.h#L647
 VALUE rb_big_sq_fast(VALUE x);
 VALUE rb_big2str_poweroftwo(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)
 VALUE rb_big_mul_gmp(VALUE x, VALUE y);
 VALUE rb_big2str_gmp(VALUE x, int base);
Index: bignum.c
===================================================================
--- bignum.c	(revision 42796)
+++ bignum.c	(revision 42797)
@@ -3972,6 +3972,117 @@ rb_str_to_inum(VALUE str, int base, int https://github.com/ruby/ruby/blob/trunk/bignum.c#L3972
     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
 
 static VALUE
Index: test/-ext-/bignum/test_str2big.rb
===================================================================
--- test/-ext-/bignum/test_str2big.rb	(revision 0)
+++ test/-ext-/bignum/test_str2big.rb	(revision 42797)
@@ -0,0 +1,30 @@ https://github.com/ruby/ruby/blob/trunk/test/-ext-/bignum/test_str2big.rb#L1
+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

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]