summaryrefslogtreecommitdiff
path: root/bignum.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-09 20:39:05 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-09 20:39:05 +0000
commit192085bad3471ed7442a147f86a3c85c1958307c (patch)
treeaf94ea1af54081700de846cbe6ec64d2f86cb2aa /bignum.c
parent79042beeced5bc70183c405a8e2debbf6cd0bf70 (diff)
* bignum.c (absint_numwords_small): New function.
(absint_numwords_generic): Use absint_numwords_small if possible. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41201 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r--bignum.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/bignum.c b/bignum.c
index 3824efadb5..a0a241a066 100644
--- a/bignum.c
+++ b/bignum.c
@@ -555,7 +555,7 @@ absint_numwords_bytes(size_t numbytes, int nlz_bits_in_msbyte, size_t word_numbi
}
else {
s = q - 1;
- t = word_numbits + r * CHAR_BIT - nlz_bits_in_msbyte;
+ t = word_numbits - nlz_bits_in_msbyte + r * CHAR_BIT;
}
div = s + t / word_numbits;
mod = t % word_numbits;
@@ -566,6 +566,20 @@ absint_numwords_bytes(size_t numbytes, int nlz_bits_in_msbyte, size_t word_numbi
}
size_t
+absint_numwords_small(size_t numbytes, int nlz_bits_in_msbyte, size_t word_numbits, size_t *nlz_bits_ret)
+{
+ size_t val_numbits = numbytes * CHAR_BIT - nlz_bits_in_msbyte;
+ size_t div = val_numbits / word_numbits;
+ size_t mod = val_numbits % word_numbits;
+ size_t numwords;
+ size_t nlz_bits;
+ numwords = mod == 0 ? div : div + 1;
+ nlz_bits = mod == 0 ? 0 : word_numbits - mod;
+ *nlz_bits_ret = nlz_bits;
+ return numwords;
+}
+
+size_t
absint_numwords_generic(size_t numbytes, int nlz_bits_in_msbyte, size_t word_numbits, size_t *nlz_bits_ret)
{
VALUE val_numbits, word_numbits_v;
@@ -634,7 +648,16 @@ rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
numbytes = rb_absint_size(val, &nlz_bits_in_msbyte);
- if (word_numbits % CHAR_BIT == 0) {
+ if (numbytes <= SIZE_MAX / CHAR_BIT) {
+ numwords = absint_numwords_small(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
+#if 0
+ size_t numwords0, nlz_bits0;
+ numwords0 = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits0);
+ assert(numwords0 == numwords);
+ assert(nlz_bits0 == nlz_bits);
+#endif
+ }
+ else if (word_numbits % CHAR_BIT == 0) {
numwords = absint_numwords_bytes(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
#if 0
size_t numwords0, nlz_bits0;