зеркало из https://github.com/github/ruby.git
* bignum.c (rb_big_pow): Retry if y is a Bignum and it is
representable as a Fixnum. Use rb_absint_numwords. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41667 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
186b494a81
Коммит
c72186f4c2
|
@ -1,3 +1,9 @@
|
|||
Thu Jun 27 00:23:57 2013 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* 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@ruby-lang.org>
|
||||
|
||||
* ext/bigdecimal/bigdecimal.c (BigDecimal_save_rounding_mode): fix typo.
|
||||
|
|
13
bignum.c
13
bignum.c
|
@ -4578,6 +4578,7 @@ rb_big_pow(VALUE x, VALUE y)
|
|||
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)
|
|||
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)
|
|||
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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче