Eneboo - Documentación para desarrolladores
|
00001 /* -*- C++ -*- */ 00002 00010 // lsb is due to Leiserson, Prokop, Randall (MIT). 00011 // msb is also a fast implementation of floor(lg_2). 00012 00013 #ifndef _BITINDEX_H_ 00014 #define _BITINDEX_H_ 00015 00016 #include <assert.h> 00017 00018 namespace HL { 00019 00020 class BitIndex { 00021 private: 00022 00023 enum { debruijn32 = 0x077CB531UL }; 00024 static int index32[32]; 00025 static unsigned long lgtable[16]; 00026 static unsigned long on[32]; 00027 static unsigned long off[32]; 00028 00029 void setup (void); 00030 00031 public: 00032 00033 BitIndex (void); 00034 ~BitIndex (void) {} 00035 00036 // Set bit_index in b (to 1). 00037 static void set (unsigned long &b, int index) 00038 { 00039 assert (index >= 0); 00040 assert (index < 32); 00041 b |= on[index]; 00042 } 00043 00044 // Reset bit_index in b (set it to 0). 00045 static void reset (unsigned long &b, int index) 00046 { 00047 assert (index >= 0); 00048 assert (index < 32); 00049 b &= off[index]; 00050 } 00051 00052 // Find the least-significant bit. 00053 static int lsb (unsigned long b) 00054 { 00055 //#if 0 00056 #if 0 // i386 00057 // Intel x86 code. 00058 register unsigned long index = 0; 00059 if (b > 0) { 00060 asm ("bsfl %1, %0" : "=r" (index) : "r" (b)); 00061 } 00062 return index; 00063 #else 00064 b &= (unsigned long) -((signed long) b); 00065 b *= debruijn32; 00066 b >>= 27; 00067 return index32[b]; 00068 #endif 00069 } 00070 00071 // Find the most-significant bit. 00072 static int msb (unsigned long b) 00073 { 00074 #if 0 // i386 00075 // Intel x86 code. 00076 register unsigned long index = 0; 00077 if (b > 0) { 00078 asm ("bsrl %1, %0" : "=r" (index) : "r" (b)); 00079 } 00080 return index; 00081 #else 00082 int l = 0; 00083 // b < 2^32 00084 if (b >= 65536) { 00085 l += 16; 00086 b >>= 16; 00087 } 00088 // b < 2^16 00089 if (b >= 256) { 00090 l += 8; 00091 b >>= 8; 00092 } 00093 // b < 2^8 00094 if (b >= 16) { 00095 l += 4; 00096 b >>= 4; 00097 } 00098 return l + lgtable[b]; 00099 #endif 00100 } 00101 00102 00103 }; 00104 00105 }; 00106 00107 #endif