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

ruby-changes:29615

From: akr <ko1@a...>
Date: Thu, 27 Jun 2013 00:27:32 +0900 (JST)
Subject: [ruby-changes:29615] akr:r41667 (trunk): * bignum.c (rb_big_pow): Retry if y is a Bignum and it is

akr	2013-06-27 00:27:20 +0900 (Thu, 27 Jun 2013)

  New Revision: 41667

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

  Log:
    * bignum.c (rb_big_pow): Retry if y is a Bignum and it is
      representable as a Fixnum.
      Use rb_absint_numwords.

  Modified files:
    trunk/ChangeLog
    trunk/bignum.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 41666)
+++ ChangeLog	(revision 41667)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Jun 27 00:23:57 2013  Tanaka Akira  <akr@f...>
+
+	* bignum.c (rb_big_pow): Retry if y is a Bignum and it is
+	  representable as a Fixnum.
+	  Use rb_absint_numwords.
+
 Wed Jun 26 23:53:00 2013  Charlie Somerville  <charliesome@r...>
 
 	* ext/bigdecimal/bigdecimal.c (BigDecimal_save_rounding_mode): fix typo.
Index: bignum.c
===================================================================
--- bignum.c	(revision 41666)
+++ bignum.c	(revision 41667)
@@ -4578,6 +4578,7 @@ rb_big_pow(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L4578
     double d;
     SIGNED_VALUE yy;
 
+  again:
     if (y == INT2FIX(0)) return INT2FIX(1);
     switch (TYPE(y)) {
       case T_FLOAT:
@@ -4587,6 +4588,9 @@ rb_big_pow(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L4588
 	break;
 
       case T_BIGNUM:
+	y = bignorm(y);
+	if (FIXNUM_P(y))
+	    goto again;
 	rb_warn("in a**b, b may be too big");
 	d = rb_big2dbl(y);
 	break;
@@ -4599,11 +4603,12 @@ rb_big_pow(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L4603
 	else {
 	    VALUE z = 0;
 	    SIGNED_VALUE mask;
-	    const long xlen = RBIGNUM_LEN(x);
-            const long xbits = BITSPERDIG*xlen - nlz(RBIGNUM_DIGITS(x)[xlen-1]);
-	    const long BIGLEN_LIMIT = 32*1024*1024;
+            const size_t xbits = rb_absint_numwords(x, 1, NULL);
+	    const size_t BIGLEN_LIMIT = 32*1024*1024;
 
-	    if ((xbits > BIGLEN_LIMIT) || (xbits * yy > BIGLEN_LIMIT)) {
+	    if (xbits == (size_t)-1 ||
+                (xbits > BIGLEN_LIMIT) ||
+                (xbits * yy > BIGLEN_LIMIT)) {
 		rb_warn("in a**b, b may be too big");
 		d = (double)yy;
 		break;

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

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