c#位运算符和移位运算符(“<<“及“>>“)详细说明,及相关引用,声明枚举(夯实基础)

背景:

((int)CZSystemType.Api << CZSysConsts.POS_SYSTEM) + ((int)CZModuleType.待办 << CZSysConsts.POS_MODULE) + (0x0001)

公司定义一系列的枚举,出现移位运算符,现在已经忘记差不多,这里总结一下

代码演示:

namespace TestUnit
{
    class Program
    {
        static void Main(string[] args)
        {
            //Console.WriteLine(((int)CZSystemType.Api << CZSysConsts.POS_SYSTEM) + ((int)CZModuleType.待办 << CZSysConsts.POS_MODULE) + (0x0001));
            //Console.WriteLine(0x02);//2
            //Console.WriteLine(0x02 << 1);//4          
            //Console.WriteLine(0x02 << 3);//16
            //Console.WriteLine(0x02 << 24);
            //33554432即0x02 1021*1024*16          
            //简单理解就是左移位多少位数,就是乘以2的多少次方,反之除以


            //1、给用户创建、读取,修改和删除的权限
            permission parmission = permission.Create | permission.Read | permission.Update | permission.Delete;
            Console.WriteLine(parmission);

            //2、去掉用户的修改和删除权限
            parmission = parmission & ~permission.Update;
            parmission = parmission & ~permission.Delete;
            Console.WriteLine(parmission);

            //3、给用户加上修改的权限
            parmission = parmission | permission.Update;
            Console.WriteLine(parmission);

            //4、判断用户是否有创建的权限
            var isCreate = (parmission & permission.Create) != 0;
            //或者
            var isCreate2 = (parmission & permission.Create) == permission.Create;
            /*
            这时parmission枚举的值将变成0 + 1 + 4 = 5,它的ToSting()将变成“parmission.Create,
          parmission.Read”,parmission.Update; 这里我们可以解释为什么第五个值Delete是8而不能成为5。
          也就是说它的值不应该是前几项值的复合值。一个比较简单的方法
            就是用2的n次方来依次位每一项赋值,例如:1,2,4,8,16,32,64.......。
            */
        }
    }

    ///<summary>
    /// 权限枚举
    /// 注意加了[Flags] 特性后有三种写法,
    /// 一种是使用<<符号,
    /// 第二种是0x01,     
    /// 还有一种是直接写0,1,2,4,8....,
    /// 一般来说是2的n次方来表示。  
    /// 注:<<左操作符,表示对这个数进行移位。
    ///</summary>
    [Flags]
    public enum permission
    {
        Unknown = 0, // 也可以写成0x00或0                       

        Create = 1 << 0, // 0x01或1                 

        Read = 1 << 1,  //0x02或2

        Update = 1 << 2, //0x04或4

        Delete = 1 << 3  //0x08或8
    }

详细说明如下:

是多种运算符中一种:

https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/

https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators

在讲移位运算符之前,先简单补充一下原码与补码的知识。

一.原码与补码

  在计算机系统中,数值一律用补码来存储(表示)。主要原因:使用补码,可以将符号位和其他位统一处理;同时减法也可按加法来处理。另外,两个补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。

  1.原码转补码分两种情况

    (1)正数的补码:与原码相同(已知原码求补码)

        例如:+9的原码是0000 1001。补码也是0000 1001。

    (2)负数的补码:符号位为1,其余位为该数绝对值的原码按位取反,然后整个数加1。

        例如:-7原码为1000 0111(高位为符号位,1表示负数,0表示正数),补码为1111 1001.

  2.补码转原码也分两种情况(已知补码求原码)

    (1)正数的原码:与补码相同

        例如:+9的补码是0000 1001。原码也是0000 1001。

    (2)负数的原码:符号位为1,其余位为该该补码按位取反,然后整个数加1。

        例如:-7的补码是1111 1001,原码是1000 0111。

二.移位运算符

  “<<”和“>>”运算符用于执行移位运算,分别称为左移位运算符和右移位运算符。对于X<<N和X>>N形式的运算,含义是将X向左或向右移动N位,得到的结果的类型与X相同。此处,X的类型只能是int,uint、long或ulong,N的类型只能是int,N的类型只能是int,或者显示转换为这些类型之一,否则变异程序时会出现错误。

  1.左移位运算符

    使用左移位(<<)运算符可以将数向左移位。其作用是所有的位都向左移动指定的次数,高次位就会丢失,低位以0来填充。

    注意:如果第一个操作数是int或uint(32位数),则移位数有第二个操作数的低5位给出(原因是:低5位可表示的数的范围是0~24+23+22+21+20,即0~31,足够一个       32位数移位使用),如果第一个操作数是long或ulong(64位数),则移位数由第二个操作数的低6位给出(原因同上)。在左移时,第一个操作数的高序位被放弃,低序空位       用0填充。移位操作从不导致溢出。

    (1)正数左移位(以85为例,可以视作int 、long、uint、ulong之一,此处视为uint类型,32位)

                      85的二进制表示:      0000 0000 0000 0000 0000 0000 0101 0101

        85左移(<<)3位:             0000 0000 0000 0000 0000 0010 1010 1000

        移位后的结果十进制表示:      680

     (2)负数左移位(以-85为例,可以视作int 、long之一,此处视为int,32位)

        -85的二进制补码表示:      1111 1111 1111 1111 1111 1111 1010 1011

        -85左移(<<)3位:        1111 1111 1111 1111 1111 1101 0101 1000

        移位后结果的原码表示:       1000 0000 0000 0000 0000 0010 1010 1000

        移位后的结果十进制表示:     -680

  2.右移位运算符

    右移位运算符(>>)是把数向右移位,其作用是所有的位都向右移动指定的次数。

    注意:如果第一个操作数是int或uint(32位数),则移位数有第二个操作数的低5位给出(原因是:低5位可表示的数的范围是0~24+23+22+21+20,即0~31,足够一个       32位数移位使用),如果第一个操作数是long或ulong(64位数),则移位数由第二个操作数的低6位给出(原因同上)。如果第一个操作数为int或long,则右移位是算数移       位(高序空位设置为符号位)。如果第一个操作数是uint或ulong类型,则右移位是逻辑移位(高位填充0)。

    (1)正数右移位(以85为例,可以视作int 、long、uint、ulong之一,按哪个规则都行)

        85的二进制表示:      0000 0000 0000 0000 0000 0000 0101 0101

        85右移(>>)3位:             0000 0000 0000 0000 0000 0000 0000 1010

        移位后的结果十进制表示:      10

    (2)负数右移位(以-85为例,可以视作int 、long之一,此处视为int,32位)

        -85的二进制补码表示:      1111 1111 1111 1111 1111 1111 1010 1011

        -85左移(>>)3位:        1111 1111 1111 1111 1111 1111 1111 0101

        移位后结果的原码表示:       1000 0000 0000 0000 0000 0010 0000 1011

        移位后的结果十进制表示:     -11

后一部分:看见https://www.cnblogs.com/tjudzj/p/4190878.html这篇博文写的很详细

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值