eg_bit.c

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 #include "eg_bit.h"
00021 /* ========================================================================= */
00022 int EGbitRightShift (bit_int_t * dst,
00023                      const bit_int_t * src,
00024                      const unsigned int shift,
00025                      const unsigned int from,
00026                      const unsigned int to)
00027 {
00028   /* local variables */
00029   bit_int_t carry_on = 0;
00030   register int i;
00031   unsigned int start = from >> __EGBIT_SHIFT__;
00032 
00033   /* doing the left shift */
00034   i = (to >> __EGBIT_SHIFT__);
00035   carry_on = src[i] << (__EGBIT_WORD_SIZE__ - shift);
00036   dst[i] = src[i] >> shift;
00037   for (i--; i >= (signed) start; i--)
00038   {
00039     dst[i] = (src[i] >> shift) | carry_on;
00040     carry_on = src[i] << (__EGBIT_WORD_SIZE__ - shift);
00041   }
00042 
00043   /* ending */
00044   return 0;
00045 }
00046 
00047 /* ========================================================================= */
00048 /* ========================================================================= */
00049 int EGbitPlus (bit_int_t * dst,
00050                const bit_int_t * src,
00051                const unsigned int from,
00052                const unsigned int to)
00053 {
00054   /* local variables */
00055   bit_int_t carry_on = 0,
00056     carry_on3 = 0,
00057     carry_on2 = 0;
00058   register unsigned int i;
00059   unsigned int end = to >> __EGBIT_SHIFT__;
00060 
00061   /* doung the sum */
00062   for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00063   {
00064     carry_on2 =
00065       ((dst[i]) >> (__EGBIT_WORD_SIZE__ - 1)) | ((src[i]) >>
00066                                                  (__EGBIT_WORD_SIZE__ - 1));
00067     carry_on3 =
00068       ((dst[i]) >> (__EGBIT_WORD_SIZE__ - 1)) & ((src[i]) >>
00069                                                  (__EGBIT_WORD_SIZE__ - 1));
00070     dst[i] = dst[i] + src[i] + carry_on;
00071     carry_on2 &=
00072       (((~dst[i]) & (1ULL << (__EGBIT_WORD_SIZE__ - 1)))) >>
00073       (__EGBIT_WORD_SIZE__ - 1);
00074     carry_on = carry_on2 | carry_on3;
00075   }
00076   /* ending */
00077   return 0;
00078 }
00079 
00080 /* ========================================================================= */
00081 /* copy one bitset to another within some range [from,to] */
00082 /* ========================================================================= */
00083 int EGbitCopy (bit_int_t * const a,
00084                const bit_int_t * const b,
00085                const unsigned int from,
00086                const unsigned int to)
00087 {
00088   /* copying memory */
00089   memcpy (a + (from >> __EGBIT_SHIFT__),
00090           b + (from >> __EGBIT_SHIFT__),
00091           sizeof (bit_int_t) * ((to - from) >> __EGBIT_SHIFT__));
00092 
00093   /* ending */
00094   return 0;
00095 }
00096 
00097 /* ========================================================================= */
00098 /* tell us if a <= b bit within some range [from,to] in a vector sense. */
00099 /* ========================================================================= */
00100 int EGbitIsLeq (const bit_int_t * a,
00101                 const bit_int_t * b,
00102                 const unsigned int from,
00103                 const unsigned int to)
00104 {
00105   /* local variables */
00106   register unsigned int i;
00107   unsigned int start = from >> __EGBIT_SHIFT__;
00108 
00109   /* doing the left shift */
00110   i = (to >> __EGBIT_SHIFT__) - start;
00111   do
00112   {
00113     if (a[i] < b[i])
00114       return 1;
00115     if (a[i] > b[i])
00116       return 0;
00117   } while (i--);
00118 
00119   /* ending */
00120   return 1;
00121 }
00122 
00123 /* ========================================================================= */
00124 /* tell us if these bit fields are equal within some range [from,to[. */
00125 /* ========================================================================= */
00126 int EGbitIsEqual (const bit_int_t * a,
00127                   const bit_int_t * b,
00128                   const unsigned int from,
00129                   const unsigned int to)
00130 {
00131   /* local variables */
00132   register unsigned int i;
00133   unsigned int end = to >> __EGBIT_SHIFT__;
00134 
00135   /* doing the left shift */
00136   for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00137   {
00138     if (a[i] != b[i])
00139       return 0;
00140   }
00141 
00142   /* ending */
00143   return 1;
00144 }
00145 
00146 /* ========================================================================= */
00147 int EGbitLeftShift (bit_int_t * dst,
00148                     const bit_int_t * src,
00149                     const unsigned int shift,
00150                     const unsigned int from,
00151                     const unsigned int to)
00152 {
00153   /* local variables */
00154   bit_int_t carry_on = 0;
00155   register unsigned int i;
00156   unsigned int end = to >> __EGBIT_SHIFT__;
00157 
00158   /* doing the left shift */
00159   i = (from >> __EGBIT_SHIFT__);
00160   carry_on = src[i] >> (__EGBIT_WORD_SIZE__ - shift);
00161   dst[i] = src[i] << shift;
00162   for (i++; i <= end; i++)
00163   {
00164     dst[i] = (src[i] << shift) | carry_on;
00165     carry_on = src[i] >> (__EGBIT_WORD_SIZE__ - shift);
00166   }
00167 
00168   /* ending */
00169   return 0;
00170 }
00171 
00172 /* ========================================================================= */
00173 void EGfreeBitSet (void *bitfield,
00174                    const size_t size,
00175                    EGmemPool_t * mem)
00176 {
00177   EGmemPoolFree (bitfield, size / CHAR_BIT, mem);
00178   return;
00179 }
00180 
00181 /* ========================================================================= */
00182 int EGbitUnset (bit_int_t * dst,
00183                 const unsigned int pos)
00184 {
00185   MESSAGE (__EGBIT_DEBUG_LEVEL__,
00186            "in EGbitUnset, set bit %u (chunk %u position %u)", pos,
00187            pos >> __EGBIT_SHIFT__, pos & __EGBIT_MASK__);
00188 
00189   dst[(pos >> __EGBIT_SHIFT__)] &= (~(1 << (pos & __EGBIT_MASK__)));
00190 
00191   return 0;
00192 }
00193 
00194 /* ========================================================================= */
00195 EGbitset_t *EGnewBitSet (EGmemPool_t * mem,
00196                          size_t * n)
00197 {
00198 
00199   /* local variables */
00200   EGbitset_t *res;
00201 
00202   /* padd the size *n */
00203   if (*n & __EGBIT_MASK__)
00204     *n = *n - (*n & __EGBIT_MASK__) + __EGBIT_WORD_SIZE__;
00205 
00206   /* looking for memory */
00207   res = (EGbitset_t *) EGmemPoolMalloc (mem, (*n) / CHAR_BIT);
00208   memset (res, 0, (*n) / CHAR_BIT);
00209 
00210   /* ending */
00211   return res;
00212 }
00213 
00214 /* ========================================================================= */
00215 int EGbitOr (EGbitset_t * dst,
00216              const EGbitset_t * src,
00217              const unsigned int from,
00218              const unsigned int to)
00219 {
00220 
00221   /* local variables */
00222   unsigned int i;
00223   unsigned int end = to >> __EGBIT_SHIFT__;
00224 
00225   /* doing or */
00226   for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00227     dst[i] = dst[i] | src[i];
00228 
00229   /* ending */
00230   return 0;
00231 }
00232 
00233 /* ========================================================================= */
00234 int EGbitAnd (EGbitset_t * dst,
00235               const EGbitset_t * src,
00236               const unsigned int from,
00237               const unsigned int to)
00238 {
00239 
00240   /* local variables */
00241   unsigned int i;
00242   unsigned int end = to >> __EGBIT_SHIFT__;
00243 
00244   /* doing and */
00245   for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00246     dst[i] &= src[i];
00247 
00248   /* ending */
00249   return 0;
00250 }
00251 
00252 /* ========================================================================= */
00253 int EGbitXor (EGbitset_t * dst,
00254               const EGbitset_t * src,
00255               const unsigned int from,
00256               const unsigned int to)
00257 {
00258 
00259   /* local variables */
00260   unsigned int i;
00261   unsigned int end = to >> __EGBIT_SHIFT__;
00262 
00263   /* doing Xor */
00264   for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00265     dst[i] ^= src[i];
00266 
00267   /* ending */
00268   return 0;
00269 }
00270 
00271 /* ========================================================================= */
00272 int EGbitReset (EGbitset_t * dst,
00273                 const unsigned int from,
00274                 const unsigned int to)
00275 {
00276 
00277   /* local variables */
00278   unsigned int lo;
00279   unsigned int up;
00280 
00281   /* doing reset */
00282   lo = from >> __EGBIT_SHIFT__;
00283   up = to >> __EGBIT_SHIFT__;
00284   memset (dst + lo, 0, (up + 1 - lo) * sizeof (EGbitset_t));
00285 
00286   /* ending */
00287   return 0;
00288 }
00289 
00290 /* ========================================================================= */
00291 int EGbitTest (EGbitset_t const *const dst,
00292                const unsigned int pos)
00293 {
00294   MESSAGE (__EGBIT_DEBUG_LEVEL__,
00295            "in EGbitTest, test bit %u (chunk %u position %u)", pos,
00296            pos >> __EGBIT_SHIFT__, pos & __EGBIT_MASK__);
00297 
00298   return (dst[(pos >> __EGBIT_SHIFT__)] & (1 << (pos & __EGBIT_MASK__)));
00299 }
00300 
00301 /* ========================================================================= */
00302 int EGbitSet (EGbitset_t * const dst,
00303               const unsigned int pos)
00304 {
00305   MESSAGE (__EGBIT_DEBUG_LEVEL__,
00306            "in EGbitSet, set bit %u (chunk %u position %u)", pos,
00307            pos >> __EGBIT_SHIFT__, pos & __EGBIT_MASK__);
00308 
00309   dst[(pos >> __EGBIT_SHIFT__)] |= (1 << (pos & __EGBIT_MASK__));
00310 
00311   return 0;
00312 }
00313 
00314 /* ========================================================================= */
00315 unsigned int EGbitPrev (const EGbitset_t * dst,
00316                         const unsigned int pos)
00317 {
00318 
00319   /* local variables */
00320   register unsigned int curChunk = pos >> __EGBIT_SHIFT__,
00321     curPos = pos;
00322   EGbitset_t curMask = (1 << (pos & __EGBIT_MASK__));
00323 
00324   /* first we check the first chunk bit by bit */
00325   while (curMask)
00326   {
00327     if (dst[curChunk] & curMask)
00328       return curPos;
00329     curPos--;
00330     curMask = curMask >> 1;
00331   }
00332 
00333   /* now we look chunk by chunk */
00334   curChunk--;
00335   while ((curChunk < pos) && (!dst[curChunk]))
00336   {
00337     curChunk--;
00338     curPos -= __EGBIT_WORD_SIZE__;
00339   }
00340 
00341   /* if we run out of space we exit */
00342   if (curChunk > pos)
00343     return UINT_MAX;
00344 
00345   /* if we are here is becouse there is a one bit in the range, we are only
00346    * looking for it */
00347   curMask = 1U << __EGBIT_MASK__;
00348   while (curMask)
00349   {
00350     if (dst[curChunk] & curMask)
00351       return curPos;
00352     curPos--;
00353     curMask = curMask >> 1;
00354   }
00355 
00356   /* ending */
00357   /* if we reach this line then the code is wrong */
00358   EXIT (1, "This is due to a programming error or some memory overwrite");
00359   exit (1);
00360   return UINT_MAX;
00361 }
00362 
00363 /* ========================================================================= */
00364 unsigned int EGbitNext (const EGbitset_t * dst,
00365                         const unsigned int pos,
00366                         const unsigned int size)
00367 {
00368 
00369   /* local variables */
00370   register unsigned int curChunk = pos >> __EGBIT_SHIFT__,
00371     curPos = pos;
00372   EGbitset_t curMask = (1 << (pos & __EGBIT_MASK__));
00373 
00374   /* first we check the first chunk bit by bit */
00375   while (curMask)
00376   {
00377     if (dst[curChunk] & curMask)
00378       return curPos;
00379     curPos++;
00380     curMask = curMask << 1;
00381   }
00382 
00383   /* now we look chunk by chunk */
00384   curChunk++;
00385   curMask = 1;
00386   while ((curPos < size) && (!dst[curChunk]))
00387   {
00388     curChunk++;
00389     curPos += __EGBIT_WORD_SIZE__;
00390   }
00391 
00392   /* if we run out of space we exit */
00393   if (curPos >= size)
00394     return (UINT_MAX);
00395 
00396   /* if we are here is because there is a one bit in 
00397    * the range, we are only looking for it */
00398   while (curMask)
00399   {
00400     if (dst[curChunk] & curMask)
00401       return curPos;
00402     curPos++;
00403     curMask = curMask << 1;
00404   }
00405 
00406   /* ending */
00407   /* if we reach this line then the code is wrong */
00408   EXIT (1, "This is due to a programming error or some memory overwrite");
00409   exit (1);
00410   return UINT_MAX;
00411 }
00412 
00413 /* ========================================================================= */
00414 int EGbitSanity (void)
00415 {
00416 
00417   /* local variables */
00418   EGbitset_t mem1[10],
00419     mem2[10],
00420     mem3[10];
00421   unsigned int pos;
00422 
00423   /* sanity tests */
00424   if (sizeof (EGbitset_t) != sizeof (void *))
00425   {
00426     fprintf (stderr,
00427              "sizeof(EGbitset_t) = %zu does not equal sizeof(void*) = %zu, in file %s, line %d\n",
00428              sizeof (EGbitset_t), sizeof (void *), __FILE__, __LINE__);
00429     exit (1);
00430   }
00431   if (__EGBIT_WORD_SIZE__ != 8 * sizeof (EGbitset_t))
00432   {
00433     fprintf (stderr,
00434              "__EGBIT_WORD_SIZE__ = %u does not equal 8*sizeof(EGbitset_t) = %zu, in file %s, line %d\n",
00435              __EGBIT_WORD_SIZE__, 8 * sizeof (EGbitset_t), __FILE__, __LINE__);
00436     exit (1);
00437   }
00438   if ((1 << __EGBIT_SHIFT__) != __EGBIT_WORD_SIZE__)
00439   {
00440     fprintf (stderr,
00441              "__EGBIT_SHIFT__ = %u is not the log_2(__EGBIT_WORD_SIZE__ = %u), in file %s, line %d\n",
00442              __EGBIT_SHIFT__, __EGBIT_WORD_SIZE__, __FILE__, __LINE__);
00443     exit (1);
00444   }
00445   if ((__EGBIT_WORD_SIZE__ - 1) != __EGBIT_MASK__)
00446   {
00447     fprintf (stderr,
00448              "__EGBIT_WORD_SIZE__ -1 = %u, does not equal __EGBIT_MASK__ = %u, in file %s, line %d\n",
00449              __EGBIT_WORD_SIZE__ - 1, __EGBIT_MASK__, __FILE__, __LINE__);
00450     exit (1);
00451   }
00452 
00453 
00454   /* === now we build three memory sets and dom some 
00455    * operations we reset them all =====================*/
00456   EGbitReset (mem1, 0, 10 * __EGBIT_WORD_SIZE__ - 1);
00457   EGbitReset (mem2, 0, 10 * __EGBIT_WORD_SIZE__ - 1);
00458   EGbitReset (mem3, 0, 10 * __EGBIT_WORD_SIZE__ - 1);
00459 
00460   /* === try to find if any bit is set to one in mem1 = */
00461   pos = EGbitNext (mem1, 0, 10 * __EGBIT_WORD_SIZE__ - 1);
00462   if (pos < 10 * __EGBIT_WORD_SIZE__)
00463   {
00464     fprintf (stderr,
00465              "find in position = %u a bit set to one in a zeroed memory lot, in file %s, line %d\n",
00466              pos, __FILE__, __LINE__);
00467     exit (1);
00468   }
00469 
00470   /* == now we set some things and see what happend === */
00471   EGbitSet (mem2, 0);
00472   EGbitSet (mem2, 10 * __EGBIT_WORD_SIZE__ - 1);
00473   EGbitSet (mem2, 13);
00474   pos = EGbitNext (mem2, 0, 10 * __EGBIT_WORD_SIZE__ - 1);
00475   if (pos != 0)
00476   {
00477     fprintf (stderr,
00478              "next one find in position = %u while it should be 0, in file %s, line %d\n",
00479              pos, __FILE__, __LINE__);
00480     exit (1);
00481   }
00482   pos = EGbitNext (mem2, pos + 1, 10 * __EGBIT_WORD_SIZE__ - 1);
00483   if (pos != 13)
00484   {
00485     fprintf (stderr,
00486              "next one find in position = %u while it should be 13, in file %s, line %d\n",
00487              pos, __FILE__, __LINE__);
00488     exit (1);
00489   }
00490   pos = EGbitNext (mem2, pos + 1, 10 * __EGBIT_WORD_SIZE__ - 1);
00491   if (pos != 10 * __EGBIT_WORD_SIZE__ - 1)
00492   {
00493     fprintf (stderr,
00494              "next one find in position = %u while it should be %d, in file %s, line %d\n",
00495              pos, 10 * __EGBIT_WORD_SIZE__ - 1, __FILE__, __LINE__);
00496     exit (1);
00497   }
00498   EGbitOr (mem1, mem2, 0, 10 * __EGBIT_WORD_SIZE__ - 1);
00499   pos = EGbitNext (mem1, 0, 10 * __EGBIT_WORD_SIZE__ - 1);
00500   if (pos != 0)
00501   {
00502     fprintf (stderr,
00503              "next one find in position = %u while it should be 0, in file %s, line %d\n",
00504              pos, __FILE__, __LINE__);
00505     exit (1);
00506   }
00507   pos = EGbitNext (mem1, pos + 1, 10 * __EGBIT_WORD_SIZE__ - 1);
00508   if (pos != 13)
00509   {
00510     fprintf (stderr,
00511              "next one find in position = %u while it should be 13, in file %s, line %d\n",
00512              pos, __FILE__, __LINE__);
00513     exit (1);
00514   }
00515   pos = EGbitNext (mem1, pos + 1, 10 * __EGBIT_WORD_SIZE__ - 1);
00516   if (pos != 10 * __EGBIT_WORD_SIZE__ - 1)
00517   {
00518     fprintf (stderr,
00519              "next one find in position = %u while it should be %d, in file %s, line %d\n",
00520              pos, 10 * __EGBIT_WORD_SIZE__ - 1, __FILE__, __LINE__);
00521     exit (1);
00522   }
00523   EGbitXor (mem3, mem2, 0, 10 * __EGBIT_WORD_SIZE__ - 1);
00524   pos = EGbitNext (mem3, 0, 10 * __EGBIT_WORD_SIZE__ - 1);
00525   if (pos != 0)
00526   {
00527     fprintf (stderr,
00528              "next one find in position = %u while it should be 0, in file %s, line %d\n",
00529              pos, __FILE__, __LINE__);
00530     exit (1);
00531   }
00532   pos = EGbitNext (mem3, pos + 1, 10 * __EGBIT_WORD_SIZE__ - 1);
00533   if (pos != 13)
00534   {
00535     fprintf (stderr,
00536              "next one find in position = %u while it should be 13, in file %s, line %d\n",
00537              pos, __FILE__, __LINE__);
00538     exit (1);
00539   }
00540   pos = EGbitNext (mem3, pos + 1, 10 * __EGBIT_WORD_SIZE__ - 1);
00541   if (pos != 10 * __EGBIT_WORD_SIZE__ - 1)
00542   {
00543     fprintf (stderr,
00544              "next one find in position = %u while it should be %d, in file %s, line %d\n",
00545              pos, 10 * __EGBIT_WORD_SIZE__ - 1, __FILE__, __LINE__);
00546     exit (1);
00547   }
00548   pos = EGbitNext (mem1, 0, 10 * __EGBIT_WORD_SIZE__ - 1);
00549   if (pos != 0)
00550   {
00551     fprintf (stderr,
00552              "next one find in position = %u while it should be 0, in file %s, line %d\n",
00553              pos, __FILE__, __LINE__);
00554     exit (1);
00555   }
00556   pos = EGbitNext (mem1, pos + 1, 10 * __EGBIT_WORD_SIZE__ - 1);
00557   if (pos != 13)
00558   {
00559     fprintf (stderr,
00560              "next one find in position = %u while it should be 13, in file %s, line %d\n",
00561              pos, __FILE__, __LINE__);
00562     exit (1);
00563   }
00564   pos = EGbitNext (mem1, pos + 1, 10 * __EGBIT_WORD_SIZE__ - 1);
00565   if (pos != 10 * __EGBIT_WORD_SIZE__ - 1)
00566   {
00567     fprintf (stderr,
00568              "next one find in position = %u while it should be %d, in file %s, line %d\n",
00569              pos, 10 * __EGBIT_WORD_SIZE__ - 1, __FILE__, __LINE__);
00570     exit (1);
00571   }
00572   EGbitAnd (mem1, mem2, 0, 10 * __EGBIT_WORD_SIZE__ - 1);
00573   /* === normal ending =================================== */
00574   return 0;
00575 }
00576 
00577 /** @brief Count number of on bits on 32-bit integers.
00578  * @return Number of on bits in the given 32-bit integer
00579  * @par Description:
00580  * Parallel Count carries out bit counting in a parallel fashion. Consider n
00581  * after the first line has finished executing. Imagine splitting n into pairs
00582  * of bits. Each pair contains the number of ones in those two bit positions in
00583  * the original n. After the second line has finished executing, each nibble
00584  * contains the number of ones in those four bits positions in the original n.
00585  * Continuing this for five iterations, the 64 bits contain the number of ones
00586  * among these sixty-four bit positions in the original n. That is what we
00587  * wanted to compute.*/
00588 EGbitset_t EGbitElemBitCount (EGbitset_t n)
00589 {
00590 #define EGBIT_TWO(c)     (0x1u << (c))
00591 #define EGBIT_MASK(c)    (((unsigned int)(-1)) / (EGBIT_TWO(EGBIT_TWO(c)) + 1u))
00592 #define EGBIT_COUNT(x,c) ((x) & EGBIT_MASK(c)) + (((x) >> (EGBIT_TWO(c))) & EGBIT_MASK(c))
00593   n = EGBIT_COUNT (n, 0);
00594   n = EGBIT_COUNT (n, 1);
00595   n = EGBIT_COUNT (n, 2);
00596   n = EGBIT_COUNT (n, 3);
00597   n = EGBIT_COUNT (n, 4);
00598 #if __EGBIT_WORD_SIZE__ == 64U
00599   n = EGBIT_COUNT (n, 5);
00600 #endif
00601 #undef EGBIT_TWO
00602 #undef EGBIT_MASK
00603 #undef EGBIT_COUNT
00604   return n;
00605 }
00606 
00607  /** @brief Count the number of on-bits in a bit-map */
00608 EGbitset_t EGbitCount (bit_int_t * bitset,
00609                        const unsigned int from,
00610                        const unsigned int to)
00611 {
00612   /* local variables */
00613   unsigned int i = from >> __EGBIT_SHIFT__;
00614   unsigned int end = to >> __EGBIT_SHIFT__;
00615   EGbitset_t res = 0;
00616   for (; i <= end; i++)
00617     res += EGbitElemBitCount (bitset[i]);
00618   return res;
00619 }

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