summaryrefslogtreecommitdiff
path: root/mpz/scan1.c
diff options
context:
space:
mode:
authorMarco Bodrato <bodrato@mail.dm.unipi.it>2012-05-25 10:31:40 +0200
committerMarco Bodrato <bodrato@mail.dm.unipi.it>2012-05-25 10:31:40 +0200
commitfb12479557da895b7e955115db17d565de04abe0 (patch)
tree9b6542ccd9c2636edefd5641406fff413020a69c /mpz/scan1.c
parent69112328ee309bc2ce5c4719656821d8eb2200c8 (diff)
downloadgmp-fb12479557da895b7e955115db17d565de04abe0.tar.gz
mpz/scan1.c: Simplify.
Diffstat (limited to 'mpz/scan1.c')
-rw-r--r--mpz/scan1.c60
1 files changed, 16 insertions, 44 deletions
diff --git a/mpz/scan1.c b/mpz/scan1.c
index e7e3c7f81..5d2402697 100644
--- a/mpz/scan1.c
+++ b/mpz/scan1.c
@@ -33,7 +33,7 @@ mpz_scan1 (mpz_srcptr u, mp_bitcnt_t starting_bit) __GMP_NOTHROW
mp_srcptr u_ptr = PTR(u);
mp_size_t size = SIZ(u);
mp_size_t abs_size = ABS(size);
- mp_srcptr u_end = u_ptr + abs_size;
+ mp_srcptr u_end = u_ptr + abs_size - 1;
mp_size_t starting_limb = starting_bit / GMP_NUMB_BITS;
mp_srcptr p = u_ptr + starting_limb;
mp_limb_t limb;
@@ -55,62 +55,35 @@ mpz_scan1 (mpz_srcptr u, mp_bitcnt_t starting_bit) __GMP_NOTHROW
{
/* If it's the high limb which is zero after masking, then there's
no 1 bits after starting_bit. */
- p++;
if (p == u_end)
return ~(mp_bitcnt_t) 0;
/* Otherwise search further for a non-zero limb. The high limb is
non-zero, if nothing else. */
- for (;;)
+ search_nonzero:
+ do
{
- limb = *p;
- if (limb != 0)
- break;
+ ASSERT (p != u_end);
p++;
- ASSERT (p < u_end);
+ short_cut:
+ limb = *p;
}
+ while (limb == 0);
}
}
else
{
- mp_srcptr q;
-
/* If there's a non-zero limb before ours then we're in the ones
- complement region. Search from *(p-1) downwards since that might
- give better cache locality, and since a non-zero in the middle of a
- number is perhaps a touch more likely than at the end. */
- q = p;
- while (q != u_ptr)
- {
- q--;
- if (*q != 0)
- goto inverted;
- }
+ complement region. */
+ if (mpn_zero_p (u_ptr, starting_limb)) {
+ if (limb == 0)
+ /* Seeking for the first non-zero bit, it is the same for u and -u. */
+ goto search_nonzero;
- if (limb == 0)
- {
- /* Skip zero limbs, to find the start of twos complement. The
- high limb is non-zero, if nothing else. This search is
- necessary so the -limb is applied at the right spot. */
- do
- {
- p++;
- ASSERT (p < u_end);
- limb = *p;
- }
- while (limb == 0);
+ /* Adjust so ~limb implied by searching for 0 bit becomes -limb. */
+ limb--;
+ }
- /* Apply twos complement, and look for a 1 bit in that. Since
- limb!=0 here, also have (-limb)!=0 so there's certainly a 1
- bit. */
- limb = -limb;
- goto got_limb;
- }
-
- /* Adjust so ~limb implied by searching for 0 bit becomes -limb. */
- limb--;
-
- inverted:
/* Now seeking a 0 bit. */
/* Mask to 1 all bits before starting_bit, thus ignoring them. */
@@ -120,9 +93,9 @@ mpz_scan1 (mpz_srcptr u, mp_bitcnt_t starting_bit) __GMP_NOTHROW
then the zero immediately past the end is the result. */
while (limb == GMP_NUMB_MAX)
{
- p++;
if (p == u_end)
return (mp_bitcnt_t) abs_size * GMP_NUMB_BITS;
+ p++;
limb = *p;
}
@@ -130,7 +103,6 @@ mpz_scan1 (mpz_srcptr u, mp_bitcnt_t starting_bit) __GMP_NOTHROW
limb = ~limb;
}
- got_limb:
ASSERT (limb != 0);
count_trailing_zeros (cnt, limb);
return (mp_bitcnt_t) (p - u_ptr) * GMP_NUMB_BITS + cnt;