eg_bit.h

Go to the documentation of this file.
00001 /* EGlib "Efficient General Library" provides some basic structures and
00002  * algorithms commons in many optimization algorithms.
00003  *
00004  * Copyright (C) 2005 Daniel Espinoza and Marcos Goycoolea.
00005  * 
00006  * This library is free software; you can redistribute it and/or modify it
00007  * under the terms of the GNU Lesser General Public License as published by the
00008  * Free Software Foundation; either version 2.1 of the License, or (at your
00009  * option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful, but 
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
00013  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
00014  * License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this library; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
00019  * */
00020 /* ========================================================================= */
00021 /* bit operations over arbitrary memory segnemts 
00022  *
00023  * Version 0.0.1 2003-04-11
00024  *
00025  * - 2006-01-30
00026  *    - Change some type definitions so that to make its behavior independent
00027  *    of the plataform, we choose to use bit words of size 32 bits.
00028  * - 2005-08-01
00029  *    - Fix some types to size_t for alloc/free functions
00030  * - 2004-11-05 
00031  *    - Add EGbitsetSize macro to compute the wright size of static
00032  *      bitsets.
00033  * - 2003-05-14 
00034  *    - Fix problem in EGbitTest
00035  * - 2003-04-29 
00036  *    - Change the parameters that are not changed to const.
00037  *    - Change the definition of the function to 'extern inline int' to 
00038  *      speed-up the running time for all funcions but EGbitNext.
00039  *
00040  * */
00041 /* ========================================================================= */
00042 
00043 #ifndef __EG_BIT_H__
00044 #define __EG_BIT_H__
00045 #include <stdlib.h>
00046 #include <string.h>
00047 #include <stdio.h>
00048 #include <limits.h>
00049 #include "eg_config.h"
00050 #include "eg_macros.h"
00051 #include "eg_mempool.h"
00052 /* ============================================================================
00053    Bitset definitions and functions                                                                
00054    ==========================================================================*/
00055 
00056 
00057 /* ========================================================================== */
00058 /** @name Word lengths and related macros */
00059 /*@{*/
00060 #define __EGBIT_WORD_SIZE__ 32U
00061 #define __EGBIT_SHIFT__ 5U
00062 #define __EGBIT_MASK__ 31U
00063 /*@}*/
00064 
00065 /* ========================================================================== */
00066 /** @brief Macro to compute the right size of a bitset given the desired 
00067  * number of bits in the bitset */
00068 #define EGbitsetSize(__Bsize) (((__Bsize)>>__EGBIT_SHIFT__)+(((__Bsize)&__EGBIT_MASK__)?1:0))
00069 
00070 /* ============================================================================   
00071    all positions are in bits not in bytes   
00072    the ranged operations are performed between low_wordsize(from)   
00073    upper_wordsize(to) where low and upper are points in the wordsize generated   
00074    latice, for example, if wordsize is 32, and from is 46 and to is 90, then   
00075    the real range will be [32,95] so, be careful and remember that the range   
00076    start at zero.   
00077       
00078    this function is to check if the parameter are well set up   
00079    ========================================================================= */
00080 typedef int32_t bit_int_t;
00081 typedef bit_int_t EGbitset_t;
00082 
00083 /* ========================================================================= */
00084 /* this function only check if the internal parameters of this utilities were
00085  * well set at compile time */
00086 /* ========================================================================= */
00087 int EGbitSanity (void);
00088 
00089 /* ========================================================================= */
00090 /* free a bitset */
00091 /* ========================================================================= */
00092 extern inline void EGfreeBitSet (void *bitfield,
00093                                  const size_t size,
00094                                  EGmemPool_t * mem)
00095 {
00096   EGmemPoolFree (bitfield, size / CHAR_BIT, mem);
00097   return;
00098 }
00099 
00100 /* ========================================================================= */
00101 /* create a bitset of 'n' bits, note that the actual size might be a bit bigger
00102  * for aligment reasons, it also set all bits to zero. */
00103 /* ========================================================================= */
00104 extern inline EGbitset_t *EGnewBitSet (EGmemPool_t * mem,
00105                                        size_t * n)
00106 {
00107 
00108   /* local variables */
00109   EGbitset_t *res;
00110 
00111   /* padd the size *n */
00112   if (*n & __EGBIT_MASK__)
00113     *n = *n - (*n & __EGBIT_MASK__) + __EGBIT_WORD_SIZE__;
00114 
00115   /* looking for memory */
00116   res = (EGbitset_t *) EGmemPoolMalloc (mem, (*n) / CHAR_BIT);
00117   memset (res, 0, (*n) / CHAR_BIT);
00118 
00119   /* ending */
00120   return res;
00121 }
00122 
00123 /* ========================================================================= */
00124 /* this function implements dst |= src in the range [from,to[, where from and to
00125  * are roneded down to the nearest complete word size. */
00126 /* ========================================================================= */
00127 extern inline int EGbitOr (bit_int_t * dst,
00128                            const bit_int_t * src,
00129                            const unsigned int from,
00130                            const unsigned int to)
00131 {
00132 
00133   /* local variables */
00134   unsigned int i;
00135   unsigned int end = to >> __EGBIT_SHIFT__;
00136 
00137   /* doing or */
00138   for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00139     dst[i] = dst[i] | src[i];
00140 
00141   /* ending */
00142   return 0;
00143 }
00144 
00145 /* ========================================================================= */
00146 /* this function implements dst &= src in the range [from,to[, where from and to
00147  * are rounded down to the nearest complete word size. */
00148 /* ========================================================================= */
00149 extern inline int EGbitAnd (bit_int_t * dst,
00150                             const bit_int_t * src,
00151                             const unsigned int from,
00152                             const unsigned int to)
00153 {
00154 
00155   /* local variables */
00156   unsigned int i;
00157   unsigned int end = to >> __EGBIT_SHIFT__;
00158 
00159   /* doing and */
00160   for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00161     dst[i] &= src[i];
00162 
00163   /* ending */
00164   return 0;
00165 }
00166 
00167 /* ========================================================================= */
00168 /* this function implement right shifts in the range [from,to[, where
00169  * from and to are rounded down to the nearest complete word size */
00170 /* ========================================================================= */
00171 extern inline int EGbitRightShift (bit_int_t * dst,
00172                                    const bit_int_t * src,
00173                                    const unsigned int shift,
00174                                    const unsigned int from,
00175                                    const unsigned int to)
00176 {
00177   /* local variables */
00178   bit_int_t carry_on;
00179   register int i;
00180   unsigned int start = from >> __EGBIT_SHIFT__;
00181 
00182   /* doing the left shift */
00183   i = (to >> __EGBIT_SHIFT__);
00184   dst[i] = src[i] >> shift;
00185   carry_on = src[i] << (__EGBIT_WORD_SIZE__ - shift);
00186   for (i--; i >= (signed) start; i--)
00187   {
00188     dst[i] = (src[i] >> shift) | carry_on;
00189     carry_on = src[i] << (__EGBIT_WORD_SIZE__ - shift);
00190   }
00191 
00192   /* ending */
00193   return 0;
00194 }
00195 
00196 /* ========================================================================= */
00197 /* this function implement left shifts in the range [from,to[, where
00198  * from and to are rounded down to the nearest complete word size */
00199 /* ========================================================================= */
00200 extern inline int EGbitLeftShift (bit_int_t * dst,
00201                                   const bit_int_t * src,
00202                                   const unsigned int shift,
00203                                   const unsigned int from,
00204                                   const unsigned int to)
00205 {
00206   /* local variables */
00207   bit_int_t carry_on = 0;
00208   register unsigned int i;
00209   unsigned int end = to >> __EGBIT_SHIFT__;
00210 
00211   /* doing the left shift */
00212   i = (from >> __EGBIT_SHIFT__);
00213   carry_on = src[i] >> (__EGBIT_WORD_SIZE__ - shift);
00214   dst[i] = src[i] << shift;
00215   for (i++; i <= end; i++)
00216   {
00217     dst[i] = (src[i] << shift) | carry_on;
00218     carry_on = src[i] >> (__EGBIT_WORD_SIZE__ - shift);
00219   }
00220 
00221   /* ending */
00222   return 0;
00223 }
00224 
00225 /* ========================================================================= */
00226 /* this function set to zero the bit dst:pos (i.e. the bit in the position 'pos'
00227  * */
00228 /* ========================================================================= */
00229 extern inline int EGbitUnset (bit_int_t * dst,
00230                               const unsigned int pos)
00231 {
00232   MESSAGE (__EGBIT_DEBUG_LEVEL__,
00233            "set bit %u (chunk %u position %u)", pos,
00234            pos >> __EGBIT_SHIFT__, pos & __EGBIT_MASK__);
00235 
00236   dst[(pos >> __EGBIT_SHIFT__)] &= (~(1 << (pos & __EGBIT_MASK__)));
00237 
00238   return 0;
00239 }
00240 
00241 /* ========================================================================= */
00242 /* this function set to one the bit dst:pos (i.e. the bit in the position 'pos'
00243  * */
00244 /* ========================================================================= */
00245 extern inline int EGbitSet (bit_int_t * const dst,
00246                             const unsigned int pos)
00247 {
00248   MESSAGE (__EGBIT_DEBUG_LEVEL__,
00249            "set bit %u (chunk %u position %u)", pos,
00250            pos >> __EGBIT_SHIFT__, pos & __EGBIT_MASK__);
00251 
00252   dst[(pos >> __EGBIT_SHIFT__)] |= (1 << (pos & __EGBIT_MASK__));
00253 
00254   return 0;
00255 }
00256 
00257 /* ========================================================================= */
00258 /* this function implement x+=y function in the range [from,to[, where
00259  * from and to are rounded down to the nearest complete word size */
00260 /* ========================================================================= */
00261 extern inline int EGbitPlus (bit_int_t * dst,
00262                              const bit_int_t * src,
00263                              const unsigned int from,
00264                              const unsigned int to)
00265 {
00266   /* local variables */
00267   bit_int_t carry_on = 0,
00268     carry_on3 = 0,
00269     carry_on2 = 0;
00270   register unsigned int i;
00271   unsigned int end = to >> __EGBIT_SHIFT__;
00272 
00273   /* doung the sum */
00274   for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00275   {
00276     carry_on2 =
00277       ((dst[i]) >> (__EGBIT_WORD_SIZE__ - 1)) | ((src[i]) >>
00278                                                  (__EGBIT_WORD_SIZE__ - 1));
00279     carry_on3 =
00280       ((dst[i]) >> (__EGBIT_WORD_SIZE__ - 1)) & ((src[i]) >>
00281                                                  (__EGBIT_WORD_SIZE__ - 1));
00282     dst[i] = dst[i] + src[i] + carry_on;
00283     carry_on2 &=
00284       (((~dst[i]) & (1ULL << (__EGBIT_WORD_SIZE__ - 1)))) >>
00285       (__EGBIT_WORD_SIZE__ - 1);
00286     carry_on = carry_on2 | carry_on3;
00287   }
00288   /* ending */
00289   return 0;
00290 }
00291 
00292 /* ========================================================================= */
00293 /* copy one bitset to another within some range [from,to] */
00294 /* ========================================================================= */
00295 extern inline int EGbitCopy (bit_int_t * const a,
00296                              const bit_int_t * const b,
00297                              const unsigned int from,
00298                              const unsigned int to)
00299 {
00300   /* copying memory */
00301   memcpy (a + (from >> __EGBIT_SHIFT__),
00302           b + (from >> __EGBIT_SHIFT__),
00303           sizeof (bit_int_t) * ((to - from) >> __EGBIT_SHIFT__));
00304 
00305   /* ending */
00306   return 0;
00307 }
00308 
00309 /* ========================================================================= */
00310 /* tell us if a <= b bit fields are equal within some range [from,to[. */
00311 /* ========================================================================= */
00312 extern inline int EGbitIsLeq (const bit_int_t * a,
00313                               const bit_int_t * b,
00314                               const unsigned int from,
00315                               const unsigned int to)
00316 {
00317   /* local variables */
00318   register unsigned int i;
00319   unsigned int start = from >> __EGBIT_SHIFT__;
00320 
00321   /* doing the left shift */
00322   i = (to >> __EGBIT_SHIFT__) - start;
00323   do
00324   {
00325     if (a[i] < b[i])
00326       return 1;
00327     if (a[i] > b[i])
00328       return 0;
00329   } while (i--);
00330 
00331   /* ending */
00332   return 1;
00333 }
00334 
00335 /* ========================================================================= */
00336 /* tell us if these bit fields are equal within some range [from,to[. */
00337 /* ========================================================================= */
00338 extern inline int EGbitIsEqual (const bit_int_t * a,
00339                                 const bit_int_t * b,
00340                                 const unsigned int from,
00341                                 const unsigned int to)
00342 {
00343   /* local variables */
00344   register unsigned int i;
00345   unsigned int end = to >> __EGBIT_SHIFT__;
00346 
00347   /* doing the left shift */
00348   for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00349   {
00350     if (a[i] != b[i])
00351       return 0;
00352   }
00353 
00354   /* ending */
00355   return 1;
00356 }
00357 
00358 /* ========================================================================= */
00359 /* this function implements dst ^= src in the range [from,to[, where from and to
00360  * are rounded down to the nearest complete word size. */
00361 /* ========================================================================= */
00362 extern inline int EGbitXor (bit_int_t * dst,
00363                             const bit_int_t * src,
00364                             const unsigned int from,
00365                             const unsigned int to)
00366 {
00367 
00368   /* local variables */
00369   unsigned int i;
00370   unsigned int end = to >> __EGBIT_SHIFT__;
00371 
00372   /* doing Xor */
00373   for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00374     dst[i] ^= src[i];
00375 
00376   /* ending */
00377   return 0;
00378 }
00379 
00380 /* ========================================================================= */
00381 /* this function implements dst = 0 in the range [from,to[, where from and to
00382  * are rounded down to the nearest complete word size. */
00383 /* ========================================================================= */
00384 extern inline int EGbitReset (bit_int_t * dst,
00385                               const unsigned int from,
00386                               const unsigned int to)
00387 {
00388 
00389   /* local variables */
00390   unsigned int lo;
00391   unsigned int up;
00392 
00393   /* doing reset */
00394   lo = from >> __EGBIT_SHIFT__;
00395   up = to >> __EGBIT_SHIFT__;
00396   memset (dst + lo, 0, (up + 1 - lo) * sizeof (bit_int_t));
00397 
00398   /* ending */
00399   return 0;
00400 }
00401 
00402 /* ========================================================================= */
00403 /* this function return the value of dst:pos (i.e. the value of the bit in the
00404  * position 'pos' */
00405 /* ========================================================================= */
00406 extern inline int EGbitTest (bit_int_t const *const dst,
00407                              const unsigned int pos)
00408 {
00409   MESSAGE (__EGBIT_DEBUG_LEVEL__,
00410            "in EGbitTest, test bit %u (chunk %u position %u)", pos,
00411            pos >> __EGBIT_SHIFT__, pos & __EGBIT_MASK__);
00412 
00413   return (dst[(pos >> __EGBIT_SHIFT__)] & (1 << (pos & __EGBIT_MASK__)));
00414 }
00415 
00416 /* ========================================================================= */
00417 /* return the next one position in the bitset from 'pos' (inclusive), if no
00418  * next one position is found it return a number bigger than size */
00419 /* ========================================================================= */
00420 extern inline unsigned int EGbitNext (const bit_int_t * dst,
00421                                       const unsigned int pos,
00422                                       const unsigned int size)
00423 {
00424 
00425   /* local variables */
00426   unsigned int curChunk = pos >> __EGBIT_SHIFT__,
00427     curPos = pos;
00428   bit_int_t curMask = (1 << (pos & __EGBIT_MASK__));
00429 
00430   /* first we check the first chunk bit by bit */
00431   while (curMask)
00432   {
00433     if (dst[curChunk] & curMask)
00434       return curPos;
00435     curPos++;
00436     curMask = curMask << 1;
00437   }
00438 
00439   /* now we look chunk by chunk */
00440   curChunk++;
00441   curMask = 1;
00442   while ((curPos < size) && (!dst[curChunk]))
00443   {
00444     curChunk++;
00445     curPos += __EGBIT_WORD_SIZE__;
00446   }
00447 
00448   /* if we run out of space we exit */
00449   if (curPos >= size)
00450     return (size << 1);
00451 
00452   /* if we are here is because there is a one bit in 
00453    * the range, we are only looking for it */
00454   while (curMask)
00455   {
00456     if (dst[curChunk] & curMask)
00457       return curPos;
00458     curPos++;
00459     curMask = curMask << 1;
00460   }
00461 
00462   /* ending */
00463   /* if we reach this line then the code is wrong */
00464   EXIT (1, "This is due to a programming error or some memory overwrite");
00465   exit (1);
00466   return UINT_MAX;
00467 }
00468 
00469 /* ========================================================================= */
00470 /* return the previous one position in the bitset from 'pos' (inclusive), if no
00471  * previous one position is found it return a number bigger than pos */
00472 /* ========================================================================= */
00473 extern inline unsigned int EGbitPrev (const EGbitset_t * dst,
00474                                       const unsigned int pos)
00475 {
00476 
00477   /* local variables */
00478   register unsigned int curChunk = pos >> __EGBIT_SHIFT__,
00479     curPos = pos;
00480   EGbitset_t curMask = (1 << (pos & __EGBIT_MASK__));
00481 
00482   /* first we check the first chunk bit by bit */
00483   while (curMask)
00484   {
00485     if (dst[curChunk] & curMask)
00486       return curPos;
00487     curPos--;
00488     curMask = curMask >> 1;
00489   }
00490 
00491   /* now we look chunk by chunk */
00492   curChunk--;
00493   while ((curChunk < pos) && (!dst[curChunk]))
00494   {
00495     curChunk--;
00496     curPos -= __EGBIT_WORD_SIZE__;
00497   }
00498 
00499   /* if we run out of space we exit */
00500   if (curChunk > pos)
00501     return UINT_MAX;
00502 
00503   /* if we are here is becouse there is a one bit in the range, we are only
00504    * looking for it */
00505   curMask = 1U << __EGBIT_MASK__;
00506   while (curMask)
00507   {
00508     if (dst[curChunk] & curMask)
00509       return curPos;
00510     curPos--;
00511     curMask = curMask >> 1;
00512   }
00513 
00514   /* ending */
00515   /* if we reach this line then the code is wrong */
00516   EXIT (1, "This is due to a programming error or some memory overwrite");
00517   exit (1);
00518   return UINT_MAX;
00519 }
00520 
00521 /** @brief Count number of on bits on 32-bit integers.
00522  * @return Number of on bits in the given 32-bit integer
00523  * @par Description:
00524  * Parallel Count carries out bit counting in a parallel fashion. Consider n
00525  * after the first line has finished executing. Imagine splitting n into pairs
00526  * of bits. Each pair contains the number of ones in those two bit positions in
00527  * the original n. After the second line has finished executing, each nibble
00528  * contains the number of ones in those four bits positions in the original n.
00529  * Continuing this for five iterations, the 64 bits contain the number of ones
00530  * among these sixty-four bit positions in the original n. That is what we
00531  * wanted to compute.*/
00532 extern inline EGbitset_t EGbitElemBitCount (EGbitset_t n)
00533 {
00534 #define EGBIT_TWO(c)     (0x1u << (c))
00535 #define EGBIT_MASK(c)    (((unsigned int)(-1)) / (EGBIT_TWO(EGBIT_TWO(c)) + 1u))
00536 #define EGBIT_COUNT(x,c) ((x) & EGBIT_MASK(c)) + (((x) >> (EGBIT_TWO(c))) & EGBIT_MASK(c))
00537   n = EGBIT_COUNT (n, 0);
00538   n = EGBIT_COUNT (n, 1);
00539   n = EGBIT_COUNT (n, 2);
00540   n = EGBIT_COUNT (n, 3);
00541   n = EGBIT_COUNT (n, 4);
00542 #if __EGBIT_WORD_SIZE__ == 64U
00543   n = EGBIT_COUNT (n, 5);
00544 #endif
00545 #undef EGBIT_TWO
00546 #undef EGBIT_MASK
00547 #undef EGBIT_COUNT
00548   return n;
00549 }
00550 
00551  /** @brief Count the number of on-bits in a bit-map */
00552 extern inline EGbitset_t EGbitCount (bit_int_t * bitset,
00553                                      const unsigned int from,
00554                                      const unsigned int to)
00555 {
00556   /* local variables */
00557   unsigned int i = from >> __EGBIT_SHIFT__;
00558   unsigned int end = to >> __EGBIT_SHIFT__;
00559   EGbitset_t res = 0;
00560   for (; i <= end; i++)
00561     res += EGbitElemBitCount (bitset[i]);
00562   return res;
00563 }
00564 
00565 #endif

Generated on Mon Jan 30 08:48:52 2006 for EGlib by  doxygen 1.4.5