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

ruby-changes:30755

From: akr <ko1@a...>
Date: Thu, 5 Sep 2013 01:10:15 +0900 (JST)
Subject: [ruby-changes:30755] akr:r42834 (trunk): * bignum.c (rb_big_divrem_normal): New function.

akr	2013-09-05 01:10:06 +0900 (Thu, 05 Sep 2013)

  New Revision: 42834

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

  Log:
    * bignum.c (rb_big_divrem_normal): New function.
    
    * internal.h (rb_big_divrem_normal): Declared.
    
    * ext/-test-/bignum/div.c: New file.
    
    * test/-ext-/bignum/test_div.rb: New file.

  Added files:
    trunk/ext/-test-/bignum/div.c
    trunk/test/-ext-/bignum/test_div.rb
  Modified files:
    trunk/ChangeLog
    trunk/bignum.c
    trunk/ext/-test-/bignum/depend
    trunk/internal.h
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 42833)
+++ ChangeLog	(revision 42834)
@@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Sep  5 00:38:32 2013  Tanaka Akira  <akr@f...>
+
+	* bignum.c (rb_big_divrem_normal): New function.
+
+	* internal.h (rb_big_divrem_normal): Declared.
+
+	* ext/-test-/bignum/div.c: New file.
+
+	* test/-ext-/bignum/test_div.rb: New file.
+
 Thu Sep  5 00:08:44 2013  Tanaka Akira  <akr@f...>
 
 	* bignum.c (bigdivrem_normal): Removed.
Index: ext/-test-/bignum/depend
===================================================================
--- ext/-test-/bignum/depend	(revision 42833)
+++ ext/-test-/bignum/depend	(revision 42834)
@@ -2,5 +2,6 @@ $(OBJS): $(HDRS) $(ruby_headers) https://github.com/ruby/ruby/blob/trunk/ext/-test-/bignum/depend#L2
 
 intpack.o: intpack.c $(top_srcdir)/internal.h
 mul.o: mul.c $(top_srcdir)/internal.h
+div.o: div.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/div.c
===================================================================
--- ext/-test-/bignum/div.c	(revision 0)
+++ ext/-test-/bignum/div.c	(revision 42834)
@@ -0,0 +1,25 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/bignum/div.c#L1
+#include "ruby.h"
+#include "internal.h"
+
+static VALUE
+big(VALUE x)
+{
+    if (FIXNUM_P(x))
+        return rb_int2big(FIX2LONG(x));
+    if (RB_TYPE_P(x, T_BIGNUM))
+        return x;
+    rb_raise(rb_eTypeError, "can't convert %s to Bignum",
+            rb_obj_classname(x));
+}
+
+static VALUE
+divrem_normal(VALUE x, VALUE y)
+{
+    return rb_big_norm(rb_big_divrem_normal(big(x), big(y)));
+}
+
+void
+Init_div(VALUE klass)
+{
+    rb_define_method(rb_cInteger, "big_divrem_normal", divrem_normal, 1);
+}
Index: internal.h
===================================================================
--- internal.h	(revision 42833)
+++ internal.h	(revision 42834)
@@ -696,6 +696,7 @@ VALUE rb_big_mul_balance(VALUE x, VALUE https://github.com/ruby/ruby/blob/trunk/internal.h#L696
 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);
+VALUE rb_big_divrem_normal(VALUE x, VALUE y);
 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);
Index: bignum.c
===================================================================
--- bignum.c	(revision 42833)
+++ bignum.c	(revision 42834)
@@ -2644,6 +2644,7 @@ bary_divmod_normal(BDIGIT *qds, size_t q https://github.com/ruby/ruby/blob/trunk/bignum.c#L2644
     VALUE tmpz = 0;
     VALUE tmpyy = 0;
 
+    assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
     assert(qds ? (xn - yn + 1) <= qn : 1);
     assert(rds ? yn <= rn : 1);
 
@@ -2696,6 +2697,37 @@ bary_divmod_normal(BDIGIT *qds, size_t q https://github.com/ruby/ruby/blob/trunk/bignum.c#L2697
         ALLOCV_END(tmpz);
 }
 
+VALUE
+rb_big_divrem_normal(VALUE x, VALUE y)
+{
+    size_t xn = RBIGNUM_LEN(x), yn = RBIGNUM_LEN(y), qn, rn;
+    BDIGIT *xds = BDIGITS(x), *yds = BDIGITS(y), *qds, *rds;
+    VALUE q, r;
+
+    BARY_TRUNC(yds, yn);
+    if (yn == 0)
+        rb_num_zerodiv();
+    BARY_TRUNC(xds, xn);
+
+    if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
+        return rb_assoc_new(LONG2FIX(0), x);
+
+    qn = xn + BIGDIVREM_EXTRA_WORDS;
+    q = bignew(qn, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
+    qds = BDIGITS(q);
+
+    rn = yn;
+    r = bignew(rn, RBIGNUM_SIGN(x));
+    rds = BDIGITS(r);
+
+    bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
+
+    bigtrunc(q);
+    bigtrunc(r);
+
+    return rb_assoc_new(q, r);
+}
+
 static void
 bary_divmod(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
 {
Index: test/-ext-/bignum/test_div.rb
===================================================================
--- test/-ext-/bignum/test_div.rb	(revision 0)
+++ test/-ext-/bignum/test_div.rb	(revision 42834)
@@ -0,0 +1,19 @@ https://github.com/ruby/ruby/blob/trunk/test/-ext-/bignum/test_div.rb#L1
+require 'test/unit'
+require "-test-/bignum"
+
+class TestBignum < Test::Unit::TestCase
+  class TestDiv < Test::Unit::TestCase
+
+    SIZEOF_BDIGITS = Bignum::SIZEOF_BDIGITS
+    BITSPERDIG = Bignum::BITSPERDIG
+    BDIGMAX = (1 << BITSPERDIG) - 1
+
+    def test_divrem_normal
+      x = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 3
+      y = (1 << BITSPERDIG) | 1
+      q = (1 << BITSPERDIG) | 1
+      r = 2
+      assert_equal([q, r], x.big_divrem_normal(y))
+    end
+  end
+end

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

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