[BACK]Return to scan1.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpz

Diff for /OpenXM_contrib/gmp/mpz/Attic/scan1.c between version 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2000/09/09 14:12:57 version 1.1.1.3, 2003/08/25 16:06:33
Line 1 
Line 1 
 /* mpz_scan1(op, startbit) -- Scan for the next set bit, starting at startbit.  /* mpz_scan1 -- search for a 1 bit.
   
 Copyright (C) 1996 Free Software Foundation, Inc.  Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
   
 This file is part of the GNU MP Library.  This file is part of the GNU MP Library.
   
Line 21  MA 02111-1307, USA. */
Line 21  MA 02111-1307, USA. */
   
 #include "gmp.h"  #include "gmp.h"
 #include "gmp-impl.h"  #include "gmp-impl.h"
   #include "longlong.h"
   
 unsigned long int  
 #if __STDC__  /* mpn_scan0 can't be used for the inverted u<0 search since there might not
 mpz_scan1 (mpz_srcptr u, unsigned long int starting_bit)     be a 0 bit before the end of the data.  mpn_scan1 could be used under u>0
 #else     (except when in the high limb), but usually the search won't go very far
 mpz_scan1 (u, starting_bit)     so it seems reasonable to inline that code.  */
      mpz_srcptr u;  
      unsigned long int starting_bit;  unsigned long
 #endif  mpz_scan1 (mpz_srcptr u, unsigned long starting_bit)
 {  {
   return mpn_scan1 (u->_mp_d, starting_bit);    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;
     unsigned long  starting_limb = starting_bit / GMP_NUMB_BITS;
     mp_srcptr      p = u_ptr + starting_limb;
     mp_limb_t      limb;
     int            cnt;
   
     /* Past the end there's no 1 bits for u>=0, or an immediate 1 bit for u<0.
        Notice this test picks up any u==0 too. */
     if (starting_limb >= abs_size)
       return (size >= 0 ? ULONG_MAX : starting_bit);
   
     limb = *p;
   
     if (size >= 0)
       {
         /* Mask to 0 all bits before starting_bit, thus ignoring them. */
         limb &= (MP_LIMB_T_MAX << (starting_bit % GMP_NUMB_BITS));
   
         if (limb == 0)
           {
             /* 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 ULONG_MAX;
   
             /* Otherwise search further for a non-zero limb.  The high limb is
                non-zero, if nothing else.  */
             for (;;)
               {
                 limb = *p;
                 if (limb != 0)
                   break;
                 p++;
                 ASSERT (p < u_end);
               }
           }
       }
     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;
           }
   
         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);
   
             /* 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. */
         limb |= (CNST_LIMB(1) << (starting_bit % GMP_NUMB_BITS)) - 1;
   
         /* Search for a limb which is not all ones.  If the end is reached
            then the zero immediately past the end is the result.  */
         while (limb == GMP_NUMB_MAX)
           {
             p++;
             if (p == u_end)
               return abs_size * GMP_NUMB_BITS;
             limb = *p;
           }
   
         /* Now seeking low 1 bit. */
         limb = ~limb;
       }
   
    got_limb:
     /* Mask to 0 all bits above the lowest 1 bit. */
     ASSERT (limb != 0);
     limb &= -limb;
   
     count_leading_zeros (cnt, limb);
     return (p - u_ptr) * GMP_NUMB_BITS + GMP_LIMB_BITS - 1 - cnt;
 }  }

Legend:
Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>