bit.c
资源名称:c.rar [点击查看]
上传用户:shmaik
上传日期:2014-06-01
资源大小:45093k
文件大小:4k
源码类别:

VC书籍

开发平台:

C/C++

  1. static char rcsid[] = "$Id: H:/drh/idioms/book/RCS/bit.doc,v 1.15 1997/02/21 19:49:56 drh Exp $";
  2. #include <stdarg.h>
  3. #include <string.h>
  4. #include "assert.h"
  5. #include "bit.h"
  6. #include "mem.h"
  7. #define T Bit_T
  8. struct T {
  9. int length;
  10. unsigned char *bytes;
  11. unsigned long *words;
  12. };
  13. #define BPW (8*sizeof (unsigned long))
  14. #define nwords(len) ((((len) + BPW - 1)&(~(BPW-1)))/BPW)
  15. #define nbytes(len) ((((len) + 8 - 1)&(~(8-1)))/8)
  16. #define setop(sequal, snull, tnull, op) 
  17. if (s == t) { assert(s); return sequal; } 
  18. else if (s == NULL) { assert(t); return snull; } 
  19. else if (t == NULL) return tnull; 
  20. else { 
  21. int i; T set; 
  22. assert(s->length == t->length); 
  23. set = Bit_new(s->length); 
  24. for (i = nwords(s->length); --i >= 0; ) 
  25. set->words[i] = s->words[i] op t->words[i]; 
  26. return set; }
  27. unsigned char msbmask[] = {
  28. 0xFF, 0xFE, 0xFC, 0xF8,
  29. 0xF0, 0xE0, 0xC0, 0x80
  30. };
  31. unsigned char lsbmask[] = {
  32. 0x01, 0x03, 0x07, 0x0F,
  33. 0x1F, 0x3F, 0x7F, 0xFF
  34. };
  35. static T copy(T t) {
  36. T set;
  37. assert(t);
  38. set = Bit_new(t->length);
  39. if (t->length > 0)
  40. memcpy(set->bytes, t->bytes, nbytes(t->length));
  41. return set;
  42. }
  43. T Bit_new(int length) {
  44. T set;
  45. assert(length >= 0);
  46. NEW(set);
  47. if (length > 0)
  48. set->words = CALLOC(nwords(length),
  49. sizeof (unsigned long));
  50. else
  51. set->words = NULL;
  52. set->bytes = (unsigned char *)set->words;
  53. set->length = length;
  54. return set;
  55. }
  56. void Bit_free(T *set) {
  57. assert(set && *set);
  58. FREE((*set)->words);
  59. FREE(*set);
  60. }
  61. int Bit_length(T set) {
  62. assert(set);
  63. return set->length;
  64. }
  65. int Bit_count(T set) {
  66. int length = 0, n;
  67. static char count[] = {
  68. 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
  69. assert(set);
  70. for (n = nbytes(set->length); --n >= 0; ) {
  71. unsigned char c = set->bytes[n];
  72. length += count[c&0xF] + count[c>>4];
  73. }
  74. return length;
  75. }
  76. int Bit_get(T set, int n) {
  77. assert(set);
  78. assert(0 <= n && n < set->length);
  79. return ((set->bytes[n/8]>>(n%8))&1);
  80. }
  81. int Bit_put(T set, int n, int bit) {
  82. int prev;
  83. assert(set);
  84. assert(bit == 0 || bit == 1);
  85. assert(0 <= n && n < set->length);
  86. prev = ((set->bytes[n/8]>>(n%8))&1);
  87. if (bit == 1)
  88. set->bytes[n/8] |=   1<<(n%8);
  89. else
  90. set->bytes[n/8] &= ~(1<<(n%8));
  91. return prev;
  92. }
  93. void Bit_set(T set, int lo, int hi) {
  94. assert(set);
  95. assert(0 <= lo && hi < set->length);
  96. assert(lo <= hi);
  97. if (lo/8 < hi/8) {
  98. set->bytes[lo/8] |= msbmask[lo%8];
  99. {
  100. int i;
  101. for (i = lo/8+1; i < hi/8; i++)
  102. set->bytes[i] = 0xFF;
  103. }
  104. set->bytes[hi/8] |= lsbmask[hi%8];
  105. } else
  106. set->bytes[lo/8] |= (msbmask[lo%8]&lsbmask[hi%8]);
  107. }
  108. void Bit_clear(T set, int lo, int hi) {
  109. assert(set);
  110. assert(0 <= lo && hi < set->length);
  111. assert(lo <= hi);
  112. if (lo/8 < hi/8) {
  113. int i;
  114. set->bytes[lo/8] &= ~msbmask[lo%8];
  115. for (i = lo/8+1; i < hi/8; i++)
  116. set->bytes[i] = 0;
  117. set->bytes[hi/8] &= ~lsbmask[hi%8];
  118. } else
  119. set->bytes[lo/8] &= ~(msbmask[lo%8]&lsbmask[hi%8]);
  120. }
  121. void Bit_not(T set, int lo, int hi) {
  122. assert(set);
  123. assert(0 <= lo && hi < set->length);
  124. assert(lo <= hi);
  125. if (lo/8 < hi/8) {
  126. int i;
  127. set->bytes[lo/8] ^= msbmask[lo%8];
  128. for (i = lo/8+1; i < hi/8; i++)
  129. set->bytes[i] ^= 0xFF;
  130. set->bytes[hi/8] ^= lsbmask[hi%8];
  131. } else
  132. set->bytes[lo/8] ^= (msbmask[lo%8]&lsbmask[hi%8]);
  133. }
  134. void Bit_map(T set,
  135. void apply(int n, int bit, void *cl), void *cl) {
  136. int n;
  137. assert(set);
  138. for (n = 0; n < set->length; n++)
  139. apply(n, ((set->bytes[n/8]>>(n%8))&1), cl);
  140. }
  141. int Bit_eq(T s, T t) {
  142. int i;
  143. assert(s && t);
  144. assert(s->length == t->length);
  145. for (i = nwords(s->length); --i >= 0; )
  146. if (s->words[i] != t->words[i])
  147. return 0;
  148. return 1;
  149. }
  150. int Bit_leq(T s, T t) {
  151. int i;
  152. assert(s && t);
  153. assert(s->length == t->length);
  154. for (i = nwords(s->length); --i >= 0; )
  155. if ((s->words[i]&~t->words[i]) != 0)
  156. return 0;
  157. return 1;
  158. }
  159. int Bit_lt(T s, T t) {
  160. int i, lt = 0;
  161. assert(s && t);
  162. assert(s->length == t->length);
  163. for (i = nwords(s->length); --i >= 0; )
  164. if ((s->words[i]&~t->words[i]) != 0)
  165. return 0;
  166. else if (s->words[i] != t->words[i])
  167. lt |= 1;
  168. return lt;
  169. }
  170. T Bit_union(T s, T t) {
  171. setop(copy(t), copy(t), copy(s), |)
  172. }
  173. T Bit_inter(T s, T t) {
  174. setop(copy(t),
  175. Bit_new(t->length), Bit_new(s->length), &)
  176. }
  177. T Bit_minus(T s, T t) {
  178. setop(Bit_new(s->length),
  179. Bit_new(t->length), copy(s), & ~)
  180. }
  181. T Bit_diff(T s, T t) {
  182. setop(Bit_new(s->length), copy(t), copy(s), ^)
  183. }