位操作:BitVector32结构 z

目录

BitVector32结构体位于System.Collections.Specialized命名空间内,相对.NET中另外一个位容器BitArray,他的优点是速度快,占用空间小,并可以存储小数字。他内部用一个32位的整数来存储数据,因此只能存储32位的比特数据。

返回目录

温习位操作

在看BitVector32前,温习一下简单的位操作还是很有必要的,常见的位操作无非就是与(AND),或(OR),非(NOT)。一般情况下,将一位设置成1就是把这个为或1的操作,将一位设置成0就是把这个位与0的操作。同时或0,与1结果不变。

这样的话,比如一个8位的数据:

0000 1111

我们想把第二个0设置成1,那么把他和下面这个数进行或操作:

0100 0000

结果就是

0100 1111

第二位变成了1

还是这个数

0000 1111

如果想把最后一个1设置成0,那么把他和下面这个数进行与操作

1111 1110

结果就是

0000 1110

那么我们可以这样总结一下:

想要操作一个位,我们把其他位设置成0,把这个位设置成1,这个数就是所谓的位掩码(也称位屏蔽,MSDN里用的是位屏蔽)。

那么如果想打开一个位(就是把这个位设置成1):源数据 = 源数据 OR 位掩码。

如果想关掉一个位(就是把这个位设置成0):源数据 = 源数据 AND 位掩码取反。

(位掩码取反就是非(NOT)操作:0变成1,1变成0)。

返回目录

BitVector32的位操作

了解了基本位操作BitVector32的理解就会简单多了。

首先BitVector32本质上用一个32位的数来表示数据,那么初始化BitVector32结构时必须制定一个最初值,用户可以传入一个int或者另一个已经存在的BitVector32来构造一个新的BitVector32.

BitVector32的Data属性返回一个int用来表示内部数据,如果用来显示BitVector32的内容,这个Data是没有意义的,因为他是十进制化的结果,这时候用BitVector32的ToString方法就可以返回有用的文字说明。

BitVector32 bits =newBitVector32(0xF); //初始化BitVector32:设置低4位为1  0x 00 00 00 00 00 00 00 0F Console.WriteLine(bits.Data); //(十六进制)0xF 等于 (二进制)1111 等于 (十进制)15 所以输出15 Console.WriteLine(bits.ToString()); //输出:BitVector32{00000000000000000000000000001111} (看得出来:后四位是1)

接下来就是最重要的位操作了。

BitVector32结构体提供索引器(Indexer)可以直接通过bool对象操作BitVector32结构,索引器参数是int,这个int可不是指第几位的意思(BitArray中的索引器是第几位),而是需要一个位掩码(位屏蔽),通过这个BitVector32通过这个位掩码来操作内部比特位,来看看Reflector下BitVector32索引器的源码

structBitVector32 { //data 就是 BitVector32的Data属性的对应字段 publicboolthis[int bit]     { get         { return ((this.data & bit) == ((ulong)bit)); //通过数据和掩码的与操作,来将其他位清0,保留掩码的设置位 //如果操作后的结果等于掩码,很显然这是操作位就是1,返回true //否则的话,返回false         } set         { if (value)             { this.data |= (uint)bit; //数据 = 数据 OR 掩码,将指定位设置成1             } else             { this.data &= (uint)~bit; //数据 = 数据 AND 掩码取反,将指定位设置成0 //C# 取反位操作运算符:~             }         }     }
}

上面代码我加了注释,可以看到,BitVector32的位操作就是利用普通位掩码的操作。

好了那么用BitVector32索引器操作其实就是定义好位掩码,接着取回信息或者赋值就可以了。

//注意using System.Collections.Specialized;
int mask1 =1; //掩码代表最后一位:二进制表示:0...0001 int mask2 =4; //掩码代表倒数第三位:二进制表示:0...0000100
BitVector32 bits =newBitVector32(-1); //-1补码:1...1111 //设置BitVector32全部为1 Console.WriteLine(bits);
Console.WriteLine("设置最后一位和倒数第三位位0"); bits[mask1] = bits[mask2] =false; Console.WriteLine(bits);
Console.WriteLine("设置倒数第三位为1"); bits[mask2] =true; Console.WriteLine(bits);

输出:

BitVector32{11111111111111111111111111111111} 设置最后一位和倒数第三位位0 BitVector32{11111111111111111111111111111010} 设置倒数第三位为1 BitVector32{11111111111111111111111111111110}

返回目录

CreateMask方法

BitVector还有一个CreateMask方法,他的作用就是方便用户定义位掩码。

CreateMask(无参数):返回第一个位(最低位)的位掩码,那么就是0…00001,十进制的话就是1

CreareMask(int):首先判断一直位掩码的合法性,并返回向左移1位的结果。

参考CreateMask的源代码:

publicstaticint CreateMask(int previous) { if (previous ==0)     { return1;     } if (previous ==-2147483648) //这个数等于Int32.MinValue 二进制是100...0,无法再向左移位,因此异常     { thrownewInvalidOperationException(SR.GetString("BitVectorFull")); //抛出异常     } return (previous <<1); //向左移1位 }

当然如果你掌握了上述位操作和位掩码的概念,我个人感觉CreateMask有点多此一举,我们就直接用MSDN的例子(我改了改注释)

// 初始化BitVector32:全部0 BitVector32 myBV =newBitVector32(0);
// 创建最低位的掩码,然后陆续创建倒数第二位,倒数第三位……倒数第五位的掩码 int myBit1 =BitVector32.CreateMask(); int myBit2 =BitVector32.CreateMask(myBit1); int myBit3 =BitVector32.CreateMask(myBit2); int myBit4 =BitVector32.CreateMask(myBit3); int myBit5 =BitVector32.CreateMask(myBit4); Console.WriteLine("最初值: \t{0}", myBV.ToString());
// 设置倒数第三位为1 myBV[myBit3] =true; Console.WriteLine("myBit3 = TRUE \t{0}", myBV.ToString());
// 将掩码加起来,同时设置两个位 myBV[myBit4 + myBit5] =true; Console.WriteLine("myBit4 + myBit5 = TRUE \t{0}", myBV.ToString()); myBV[myBit1 | myBit2] =true; Console.WriteLine("myBit1 | myBit2 = TRUE \t{0}", myBV.ToString());

输出:

最初值:                 BitVector32{00000000000000000000000000000000} myBit3 = TRUE           BitVector32{00000000000000000000000000000100} myBit4 + myBit5 = TRUE  BitVector32{00000000000000000000000000011100} myBit1 | myBit2 = TRUE  BitVector32{00000000000000000000000000011111}

如果你手动输出上面例子中的myBit1-5的值,其实就是我们上面讲到的倒数一到五位的掩码值。

位操作:BitVector32结构 z,布布扣,bubuko.com

时间: 2024-12-28 05:20:00

位操作:BitVector32结构 z的相关文章

位数组(BitArray,BitVector32)

BitVector32结构效率高,位数不可变 BitArray效率低,位数可以变 ========================================BitArray using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace ConsoleA

C#编程(维数组)----------位数组

位数组 如果需要处理很多位,就可以使用BitArray类和BitVector32.BitArray位于命名空间System.Collections中. BitVector32位于命名空间System.Collections.Speciallized. BitArray类 类BitArray是一个引用引用类型,包含一个int数组,没32位使用一个新整数.和bool类型的数组bool[]差不多 案例: using System; using System.Collections; using Sys

C#高级编程五十七天----位数组

位数组 如果需要处理很多位,就可以使用BitArray类和BitVector32.BitArray位于命名空间System.Collections中. BitVector32位于命名空间System.Collections.Speciallized. BitArray类 类BitArray是一个引用引用类型,包含一个int数组,没32位使用一个新整数.和bool类型的数组bool[]差不多 案例: using System; using System.Collections; using Sys

【读书笔记】C#高级编程 第十章 集合

(一)概述 数组的大小是固定的.如果元素个数是动态的,就应使用集合类. List<T>是与数组相当的集合类.还有其它类型的集合:队列.栈.链表.字典和集. (二)列表 1.创建列表 调用默认的构造函数,就可以创建列表对象.在泛型类List<T>中,必须为声明为列表的值指定类型.使用默认构造函数创建一个空列表.元素添加到列表后,列表的容量会扩大,每次添加元素达到容量上限后,容量将重新设置为原来的2倍. 例子: List<string> strList = new List

02.C#集合

1.集合接口与集合类型 (1)集合的命名空间 大多数集合类都可以在System.Collections和System.Collections.Generic名称空间中找到.泛型集合位于System.Collections.Generic名称空间中:专用于特定类型的集合类位于System.Collections.Specialized名称空间中:线程安全的集合位于System.Collections.Concurrent名称空间中. (2)集合接口介绍 1.IEnumerable与IEnumera

C#学习笔记 ----集合

List<T>是与数组相当的集合类.其他类型的集合:队列.栈.链表和字典. IEnumerable<T>如果将foreach语句用于集合,就需要IEnumerable接口.这个接口定义了方法GetEnumerator(),它返回一个实现了IEnumerator接口的枚举. ICollection<T>接口由泛型集合类实现.使用这个接口可以获得集合中的元素个数,把集合复制到数组中,还可以从集合中添加和删除元素. IList<T>接口用于可通过位置访问其中的元素

学习笔记(三)——ls命令、Linux目录结构、cd命令、PATH、快捷键

1.ls 命令: ls 用来查看文件,是非常常用的一个命令: [[email protected] ~]# ls      //不包含隐藏文件 [[email protected] ~]# ls -a    //全部文件,包含隐藏文件 [[email protected] ~]# ls -l    //文件详细信息 [[email protected] ~]# ls -lt   //文件详细信息,按 mtime 降序 [[email protected] ~]# ls -ltr   //文件详细

IAR 数据类型/扩展关键字/位操作/SRAM操作/中断/头文件/汇编嵌入方式

--数据类型 数据类型(编译器支持 ISO/ANSI C 基本数据类型和一些附加数据类型) 1.1. 整型数据 bool 数据类型在C++语言里是默认支持的.如果你在C代码的头文件里包含stdbool.h, bool数据类型也可以使用在C语言里.也可以使用布尔值 false和 true. 1.2.浮点数据类型: 1.3.指针类型:指针有数据指针和函数指针. 1.数据指针: 数据指针的大小为8位,16位,24位.定义为:在整型数据类型后加"*"符号. 例如:char * p; 整型数据没

如何提升我的HTML&amp;CSS技术,编写有结构的代码

前言 之前写了四篇HTML和CSS的知识点,也相当于是一个知识点汇总.有需要的可以收藏,平时开发过程中应该会遇到这些点,到时候再查看这些博客可能更容易理解.从这篇开始更多的介绍开发过程经常让人头痛的前端问题,以及如何编写性能比较高的前端代码.本人也是刚入门前端的小菜,希望各位前端大牛多多纠正内容中写的不对的地方,让我提升的更快.最近看到博客园中好多前端大牛,都是在各大bat公司工作,这也是我做开发的梦想... 导航 1.基础篇 这些HTML.CSS知识点,面试和平时开发都需要 No1-No4(知