00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00029 bit_int_t carry_on = 0;
00030 register int i;
00031 unsigned int start = from >> __EGBIT_SHIFT__;
00032
00033
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
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
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
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
00077 return 0;
00078 }
00079
00080
00081
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
00089 memcpy (a + (from >> __EGBIT_SHIFT__),
00090 b + (from >> __EGBIT_SHIFT__),
00091 sizeof (bit_int_t) * ((to - from) >> __EGBIT_SHIFT__));
00092
00093
00094 return 0;
00095 }
00096
00097
00098
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
00106 register unsigned int i;
00107 unsigned int start = from >> __EGBIT_SHIFT__;
00108
00109
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
00120 return 1;
00121 }
00122
00123
00124
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
00132 register unsigned int i;
00133 unsigned int end = to >> __EGBIT_SHIFT__;
00134
00135
00136 for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00137 {
00138 if (a[i] != b[i])
00139 return 0;
00140 }
00141
00142
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
00154 bit_int_t carry_on = 0;
00155 register unsigned int i;
00156 unsigned int end = to >> __EGBIT_SHIFT__;
00157
00158
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
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
00200 EGbitset_t *res;
00201
00202
00203 if (*n & __EGBIT_MASK__)
00204 *n = *n - (*n & __EGBIT_MASK__) + __EGBIT_WORD_SIZE__;
00205
00206
00207 res = (EGbitset_t *) EGmemPoolMalloc (mem, (*n) / CHAR_BIT);
00208 memset (res, 0, (*n) / CHAR_BIT);
00209
00210
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
00222 unsigned int i;
00223 unsigned int end = to >> __EGBIT_SHIFT__;
00224
00225
00226 for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00227 dst[i] = dst[i] | src[i];
00228
00229
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
00241 unsigned int i;
00242 unsigned int end = to >> __EGBIT_SHIFT__;
00243
00244
00245 for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00246 dst[i] &= src[i];
00247
00248
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
00260 unsigned int i;
00261 unsigned int end = to >> __EGBIT_SHIFT__;
00262
00263
00264 for (i = (from >> __EGBIT_SHIFT__); i <= end; i++)
00265 dst[i] ^= src[i];
00266
00267
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
00278 unsigned int lo;
00279 unsigned int up;
00280
00281
00282 lo = from >> __EGBIT_SHIFT__;
00283 up = to >> __EGBIT_SHIFT__;
00284 memset (dst + lo, 0, (up + 1 - lo) * sizeof (EGbitset_t));
00285
00286
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
00320 register unsigned int curChunk = pos >> __EGBIT_SHIFT__,
00321 curPos = pos;
00322 EGbitset_t curMask = (1 << (pos & __EGBIT_MASK__));
00323
00324
00325 while (curMask)
00326 {
00327 if (dst[curChunk] & curMask)
00328 return curPos;
00329 curPos--;
00330 curMask = curMask >> 1;
00331 }
00332
00333
00334 curChunk--;
00335 while ((curChunk < pos) && (!dst[curChunk]))
00336 {
00337 curChunk--;
00338 curPos -= __EGBIT_WORD_SIZE__;
00339 }
00340
00341
00342 if (curChunk > pos)
00343 return UINT_MAX;
00344
00345
00346
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
00357
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
00370 register unsigned int curChunk = pos >> __EGBIT_SHIFT__,
00371 curPos = pos;
00372 EGbitset_t curMask = (1 << (pos & __EGBIT_MASK__));
00373
00374
00375 while (curMask)
00376 {
00377 if (dst[curChunk] & curMask)
00378 return curPos;
00379 curPos++;
00380 curMask = curMask << 1;
00381 }
00382
00383
00384 curChunk++;
00385 curMask = 1;
00386 while ((curPos < size) && (!dst[curChunk]))
00387 {
00388 curChunk++;
00389 curPos += __EGBIT_WORD_SIZE__;
00390 }
00391
00392
00393 if (curPos >= size)
00394 return (UINT_MAX);
00395
00396
00397
00398 while (curMask)
00399 {
00400 if (dst[curChunk] & curMask)
00401 return curPos;
00402 curPos++;
00403 curMask = curMask << 1;
00404 }
00405
00406
00407
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
00418 EGbitset_t mem1[10],
00419 mem2[10],
00420 mem3[10];
00421 unsigned int pos;
00422
00423
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
00455
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
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
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
00574 return 0;
00575 }
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
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
00608 EGbitset_t EGbitCount (bit_int_t * bitset,
00609 const unsigned int from,
00610 const unsigned int to)
00611 {
00612
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 }