BitSet,是
C++语言的一个
类库,用来方便地管理一系列的bit位而不用程序员自己来写代码。
操作
c++
C++语言的一个类库,用来方便地管理一系列的bit位而不用程序员自己来写代码。
bitset除了可以访问指定下标的bit位以外,还可以把它们作为一个整数来进行某些统计。
可以如下声明一个该类型变量:
bitsetvarm (M)
其中varm为变量名。
N表示该类型在内存中占的位数,是二进制。
M表示变量varm的初始值。
声明操作
用整
值类型表示
位向量的问题在于:使用位操作符来设置复位和测试单独的位层次比较低也比较复杂.
例如:用整值类型将第27 位设置为1, 我们这样写
quiz1 |= 1<<27;
而用bitset 来做我们可以写
quizl[ 27 ] = 1;
或
quiz1.set( 27 );
#include
声明1:
bitset 有三种声明方式。在缺省定义中,我们只需简单地指明位向量的长度。例如:
bitset< 32 > bitvec;
声明了一个含有32
个位的bitset,对象位的顺序从0 到31。缺省情况下所有的位都被初始化为0 。
1.any():
为了测试bitset 对象是否含有被设置为1的位,我们可以使用any()操作
当bitset对象的一位或多个位被设置为1 时any()返回true
例如,对于bitvec ,如下测试
bool is_set = bitvec.any();
它的结果当然是false。
相反,如果bitset 对象的所有位都被设置为0 ,则none()操作返回true
例如,对于bitvec 测试
bool is_
not_set = bitvec.none();
结果为true
3.count():
count()操作返回被设置为1的位的个数.
int bits_set = bitvec.count();
4.set():
我们可以用set()操作或者下标
操作符来设置某个单独的位
for ( int index = 0; index < 32; ++ index )
if ( index % 2 == 0 )
bitvec[ index ] = 1;
5.test():
类似地,测试某个单独的位是否为1 也有两种方式
test()操作。用位置做参数,返回true或false 例如:
if ( bitvec.test( 0 ))// 我们的bitvec[0] 可以工作了!
同样地,我们也可以用下标操作符
for ( int index = 0; index < 32; ++index )
6.reset():
要将某个单独的位设置为0 ,我们可以用reset()或下标操作符
下列两个操作都将bitvec的第一位设为0.
// 两者等价都把第一位设置为0
bitvec.reset( 0 );
bitvec[ 0 ] = 0;
我们也可以用set()和reset()操作将整个bitset 对象的所有位设为1 或0 ,只要调用相应的操作而不必传递
位置参数,我们就可以做到这一点.例如
// 把所有的位设置为0
bitvec.reset();
if ( bitvec.none() != true )
// 喔! 错了
// 把所有的位设置为1if ( bitvec.any() != true )
// 喔! 又错了
7.flip():
flip()操作翻转整个bitset 对象或一个独立的位
bitvec.flip( 0 ); // 翻转第一位
bitvec[0].flip(); // 也是翻转第一位
bitvec.flip(); // 翻转所有的位的值
还有两种方法可以构造bitset 对象,它们都提供了将某位初始化为1 的方式:
一种方法是为
构造函数显式地提供一个无符号参数。bitset 对象的前N 位被初始化为参数的相应位值,例如:
bitset< 32 > bitvec2( 0xffff );
将bitvec2 的低16 位设为1
下面的bitvec3 的定义
bitset< 32 > bitvec3( 012 );
将第1 和3 位的值设置为1 假设位置从0 开0
因为 012 在
c语言中表示
八进制数字12即
二进制数字“1010”
我们还可以传递一个代表0 和1 的集合的字符串参数来构造bitset 对象如下所示
// 与bitvec3 的初始化等价
bitset< 32 > bitvec4( bitval );
bitvec4 和bitvec3 的第1 和3 位都被设置为1 而其他位保持为0
bitvec.set();
函数
MATLAB函数
设置数的某一位二进制位为1. 《
Simulink与信号处理》
使用方法
C = bitset(A,bit)
将数A的第bit二进制位设为1.
C = bitset(A,bit,V) 《Simulink与信号处理》
将数A的第bit二进制位设为V,V必须为0或1.
应用举例
例1: .
C = bitset(uint8(9),5) C = 25 将数字9(01001)的第5位设为1,C的
二进制位11001 例2: C = bitset(uint8(9),1,0)
C = 8 将数字9的第1位设为0
相关函数
bitget,
bitand, bitor, bitxor, bitcmp, bitshift
集合
BitSet 实际是由“二进制位”构成的一个Vector。如果希望高效率地保存大量“开-关”信息,就应使用
BitSet。它只有从尺寸的角度看才有意义;如果希望的高效率的访问,那么它的速度会比使用一些固有类型
的数组慢一些。
此外,BitSet 的最小长度是一个长整数(Long)的长度:64 位。这意味着假如我们准备保存比这更小的数
据,如8 位数据,那么BitSet 就显得浪费了。所以最好创建自己的类,用它容纳自己的标志位。
在一个普通的Vector 中,随我们加入越来越多的元素,集合也会
自我膨胀。在某种程度上,BitSet 也不例
外。也就是说,它有时会自行扩展,有时则不然。而且
Java 的1.0 版本似乎在这方面做得最糟,它的
BitSet 表现十分差强人意(Java1.1 已改正了这个问题)。下面这个例子展示了BitSet 是如何运作的,同时
演示了1.0 版本的错误:
//: Bits.java
// Demonstration of BitSet
public class Bits {
public static void main(String[] args) {
Random
rand = new Random();
// Take the LSB of nextInt():
byte bt = (byte)rand.nextInt();
BitSet bb = new BitSet();
for(int i = 7; i >=0; i--)
if(((1 << i) & bt) != 0)
bb.set(i);
else
bb.clear(i);
short st = (short)rand.nextInt();
BitSet bs = new BitSet();
for(int i = 15; i >=0; i--)
if(((1 << i) & st) != 0)
bs.set(i);
else
bs.clear(i);
printBitSet(bs);
int it = rand.nextInt();
BitSet bi = new BitSet();
for(int i = 31; i >=0; i--)
if(((1 << i) & it) != 0)
bi.set(i);
else
bi.clear(i);
printBitSet(bi);
// Test bitsets >= 64 bits:
BitSet b127 = new BitSet();
b127.set(127);
222
BitSet b255 = new BitSet(65);
b255.set(255);
BitSet b1023 = new BitSet(512);
// Without the following, an exception is thrown
// in the Java 1.0 implementation of BitSet:
// b1023.set(1023);
b1023.set(1024);
}
static void printBitSet(BitSet b) {
String bbits = new String();
for(int j = 0; j < b.size() ; j++)
}
} ///:~
随机数字
生成器用于创建一个随机的byte、short 和int。每一个都会转换成BitSet 内相应的位模型。此时
一切都很正常,因为BitSet 是64 位的,所以它们都不会造成最终尺寸的增大。但在Java 1.0 中,一旦
BitSet 大于64 位,就会出现一些令人迷惑不解的行为。假如我们设置一个只比BitSet 当前分配
存储空间大
出1 的一个位,它能够正常地扩展。但一旦试图在更高的位置设置位,同时不先接触边界,就会得到一个恼
人的违例。这正是由于BitSet 在Java 1.0 里不能正确扩展造成的。本例创建了一个512 位的BitSet。构建
器分配的存储空间是位数的两倍。所以假如设置位1024 或更高的位,同时没有先设置位1023,就会在Java
1.0 里得到一个违例。但幸运的是,这个问题已在Java 1.1 得到了改正。所以如果是为Java 1.0 写代码,
请尽量避免使用BitSet。
《摘自Think in Java》