summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-13 15:36:18 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-13 15:36:18 +0000
commit75a86e4733faf3f5a26aa08745e407c061d178c3 (patch)
treec5fc468018ff661cebaa3442945c91008dc9fa69
parentb9eeeac5c87591ca43fdb6aaafb521a84d7d3800 (diff)
* bignum.c (rb_big_aref): Less scan when the number is negative.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41960 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog4
-rw-r--r--bignum.c26
2 files changed, 16 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index bcd72e5369c..6f2a7156aab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Sun Jul 14 00:32:51 2013 Tanaka Akira <akr@fsij.org>
+
+ * bignum.c (rb_big_aref): Less scan when the number is negative.
+
Sun Jul 14 00:17:42 2013 Tanaka Akira <akr@fsij.org>
* bignum.c (big_shift): Avoid signed integer overflow.
diff --git a/bignum.c b/bignum.c
index fb3954624c9..9a4d032e428 100644
--- a/bignum.c
+++ b/bignum.c
@@ -5889,9 +5889,9 @@ static VALUE
rb_big_aref(VALUE x, VALUE y)
{
BDIGIT *xds;
- BDIGIT_DBL num;
unsigned long shift;
long i, s1, s2;
+ BDIGIT bit;
if (RB_TYPE_P(y, T_BIGNUM)) {
if (!RBIGNUM_SIGN(y))
@@ -5910,21 +5910,19 @@ rb_big_aref(VALUE x, VALUE y)
}
s1 = shift/BITSPERDIG;
s2 = shift%BITSPERDIG;
+ bit = (BDIGIT)1 << s2;
if (s1 >= RBIGNUM_LEN(x)) goto out_of_range;
- if (!RBIGNUM_SIGN(x)) {
- xds = BDIGITS(x);
- i = 0; num = 1;
- while (num += BIGLO(~xds[i]), ++i <= s1) {
- num = BIGDN(num);
- }
- }
- else {
- num = BDIGITS(x)[s1];
- }
- if (num & ((BDIGIT_DBL)1<<s2))
- return INT2FIX(1);
- return INT2FIX(0);
+
+ xds = BDIGITS(x);
+ if (RBIGNUM_POSITIVE_P(x))
+ return (xds[s1] & bit) ? INT2FIX(1) : INT2FIX(0);
+ if (xds[s1] & (bit-1))
+ return (xds[s1] & bit) ? INT2FIX(0) : INT2FIX(1);
+ for (i = 0; i < s1; i++)
+ if (xds[i])
+ return (xds[s1] & bit) ? INT2FIX(0) : INT2FIX(1);
+ return (xds[s1] & bit) ? INT2FIX(1) : INT2FIX(0);
}
/*