C#之位运算演示

    下面的例子对位运算:&与、|或、^异或、~非的进行了基础使用的演示及一些具体问题的实现。
     概念简述:
    & 按位与,两个二进位均为1时, 结果位为1, 否则为0。*用来遮罩,取出为1的值*。
    | 按位或,两个二进位只要有一个为1则为1,否则为0。*用来置1*。
    //^ 异或运算,不同为1,相同为0,*用来取反*
    ~ 按位取反,如:101 取反为010。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//位运算演示
namespace Bit
{
    class Program
    {
        //输出二进制方法
        static void WriteBit(string s, uint n)
        {
            Console.WriteLine(s + ":  " + Convert.ToString(n, 2));
        }

        // 0. 基本位运算操作符举例
        static void Test()
        {
            uint n;//uint:无符号的32位整数,取值范围:0到4,294,967,295。Int带符号32位整数范围为:-2,147,483,648 到 2,147,483,647 
            //将1的二进制左移四位,相当于x=1*2的4次方=16,转换为二进制即10000。
            n = 1 << 4;
            //0000 0000 0000 0000 0000 0000 0000 0001
            //0000 0000 0000 0000 0000 0000 0001 0000
            WriteBit("1<<4", n);//输出10000

            n = 0b11111111;
            //直接输出二进制11111111,ob代表二进制
            WriteBit("n", n);

            n &= 0b10101010;//&运算后新值赋给n
            // 11111111
            //& 按位与,两个二进位均为1时, 结果位为1, 否则为0。*用来遮罩,取出为1的值*
            // 10101010
            //输出:10101010
            WriteBit("&", n);

            // 10101010
            //&
            // 01010101
            //输出:0000000=0
            n &= 0b01010101;
            WriteBit("&", n);

            n = 1 << 4;
            //n=0b10000
            //| 按位或,两个二进位只要有一个为1则为1,否则为0。*用来置1*
            //n=0b00011
            //输出100011
            WriteBit("n", n);
            n = n | 0b0011;
            WriteBit("|", n);

            n = 0b00001111;
            //n=0b00001111
            //^ 异或运算,不同为1,相同为0,*用来取反*
            //n=0b00001001
            //输出110
            n = n ^ 0b1001;
            WriteBit("^", n);

            //n=0b0110
            //^
            //n=0b1001
            //输出1111
            n = n ^ 0b1001;
            WriteBit("^", n);

            //n=0000 0000 0000 0000 0000 0000 0000 1111
            //~ 按位取反 如:101 取反为010
            //输出1111 1111 1111 1111 1111 1111 1111 0000
            n = 0b00001111;
            n = ~n;
            WriteBit("~", n);
        }

        // 1. 判断是否是偶数
        static bool IsEven(uint n)
        {
            return (n & 1) == 0;//判断末位是否为0,true则是偶数
        }

        // 2. 利用Mask遮罩查看某一位的值,“1u << i”指定要操作的哪一位数(0开始计数),利用&实现遮罩取出只有1的位
        static bool CheckBit(uint n, int i)
        {
            //u表示uint类型 例:CheckBit(65536, 15),查看65536右数第15位的值,返回false该值为0
            //(65536 & 32768)
            //0000 0000 0000 0001 0000 0000 0000 0000
            //&
            //0000 0000 0000 0000 1000 0000 0000 0000
            //得:0000 0000 0000 0000 0000 0000 0000 0000 
            return (n & (1u << i)) != 0;}

        // 3. 设置某一个bit为1,SetBit(8, 2)返回12
        static uint SetBit(uint n, int i)
        {
            //ob1000
            //|
            //ob0100
            //得:1100=12,即设置n右数2位为1(从0计位)
            return n | (1u << i);}

        // 4. 设置某一个bit为0,ClearBit(65536, 16)输出0
        static uint ClearBit(uint n, int i)
        {
            uint mask = 0xffffffff;//16进制,代表二进制32个1
            //(1u << 16)=65536
            //mask=65536^65536=0
            //n & mask=32个1 & 32个0=0
            mask = mask ^ (1u << i);
            return n & mask;}

        // 5. 实际问题:IP普通形式与Uint的互转:1个uint=4个Byte(0~255)因此一个IP地址可以用一个uint表示
        static string UInt2IP(uint ip)
        {
            //例子:UInt2IP(0x7F80FFFe);输出127.128.255.254
            string IP = "";
            uint n;
            //0111 1111, 1000 0000, 1111 1111, 1111 1110。
            n = ip >> 3*8;//取出首8位第1段IP:n=7F=127
            IP += n + ".";
            n = (ip >> 2*8) & 0xFF;//从7F80中利用&的遮罩取出末8位十六进制80,第二8位第2段IP:n=128
            IP += n + ".";
            n = ip >> 1*8 & 0xFF;//从7F80FF中利用&的遮罩取出末8位十六进制FF,第三8位第3段IP:n=255
            IP += n + ".";
            n = ip & 0xFF;//从7F80FFFE中利用&的遮罩取出末8位十六进制FE,最后8位为末段IP:n=254
            IP += n;

            return IP;
        }

        //将IP转为Unit格式,上面的反例:IP2Uint(127.128.255.254)
        //返回0x7F80FFFe
        static uint IP2Uint(string IP)
        {
            string[] array_ip = IP.Split('.');
            uint ip = 0;
            for (int i=0; i<array_ip.Length; i++)
            {
                uint n = uint.Parse(array_ip[i]);//将每段IP转换为uint格式
                Console.WriteLine("左数第"+(i+1)+"段IP的unint值为:"+n);//127 128 255 254
                n <<= (3 - i) * 8;//4段IP分别左移24、16、8、0位并累加在一起
                ip += n;// 这里也可以写 ip |= n,因为4段IP值无交集;
            }

            return ip;
        }
        //计算一个整数的二进制表示里包含多少个1
        static uint Count1(uint n)
        {
            //例:Count1(65535); 返回16
            //例1:n=5=>101;
            uint count = 0;
            while (n > 0)
            {
                //n=5&4
                //n=101 & 100=100=4,count=1
                //n=100 & 011=0,count=2,跳出循环:5的二进制中包含2个1
                //每计算一次减少n中的一个1,直至n中仅剩最高位的1(10000...) & 此时的n-1(01111....)得0,跳出循环.
                //区别于遍历统计需要32次,此方法n有多少个1就执行多少次
                n &= (n - 1);
                count++;
            }
            return count;
        }
        //练习1:如何得到N个二进制1
        static uint Print1(int n)
        {
            //方法1,此方法不能输出32个1,会返回0
            //uint mask = 0xffffffff; 
            //return mask ^ (mask << n);

            //方法2,此方法可以返回32个1
            uint mask = 0xffffffff;
            return mask = mask >> (32 - n);
        }

        //练习2:如何得到N个二进制1和(32-N)个0
        static uint Print2(int n)
        {
            uint mask = 0xffffffff;
            return mask = mask << (32 - n);
        }

        static void Main(string[] args)
        {
            Console.WriteLine("-------基础例子开始----------");
            Test();
            Console.WriteLine("=======基础例子结束==========");

            uint n = 3;
            Console.WriteLine(n << 2);

            Console.WriteLine(IsEven(12));
            Console.WriteLine(Count1(65535));

            Console.WriteLine(CheckBit(65536, 15));

            Console.WriteLine(SetBit(8, 2));
            Console.WriteLine(ClearBit(65536, 16));

            string IP = UInt2IP(0x7F80FFFe);
            Console.WriteLine(IP);
            uint ip = IP2Uint(IP);
            Console.WriteLine("IP转换回uint: " + Convert.ToString(ip, 16));
            Console.WriteLine("-------------练习1&2:如何得到N个二进制1-------------");
            Console.WriteLine("请输入要返回的二进制个数:");
            int a =Convert.ToInt32(Console.ReadLine());
            //Console.WriteLine(Convert.ToString(Print1(a),2));//输出二进制结果
            Console.WriteLine(Convert.ToString(Print2(a), 2));
            Console.ReadKey();
        }}}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值