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/