added shortcuts for bases that are powers of two
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
diff --git a/bn_mp_ilogb.c b/bn_mp_ilogb.c
index 3185ca6..274cf8f 100644
--- a/bn_mp_ilogb.c
+++ b/bn_mp_ilogb.c
@@ -78,9 +78,11 @@ mp_err mp_ilogb(const mp_int *a, uint32_t base, mp_int *c)
mp_int bracket_low, bracket_high, bracket_mid, t, bi_base;
err = MP_OKAY;
+
if (a->sign == MP_NEG) {
return MP_VAL;
}
+
if (MP_IS_ZERO(a)) {
return MP_VAL;
}
@@ -88,10 +90,19 @@ mp_err mp_ilogb(const mp_int *a, uint32_t base, mp_int *c)
if (base < 2u) {
return MP_VAL;
}
- if (base == 2u) {
- mp_set_u32(c, (uint32_t)(mp_count_bits(a) - 1));
- return err;
+
+ /* A small shortcut for bases that are powers of two. */
+ if (!(base & (base - 1u))) {
+ int x, y, bit_count;
+ for (y=0; (y < 7) && !(base & 1u); y++) {
+ base >>= 1;
+ }
+ bit_count = mp_count_bits(a) - 1;
+ x = bit_count/y;
+ mp_set_u32(c, (uint32_t)(x));
+ return MP_OKAY;
}
+
if (a->used == 1) {
mp_set(c, s_digit_ilogb(base, a->dp[0]));
return err;