赞
踩
C#的常见几种位操作运算,与($)、或(|)、非(~)、异或(^)、左移(<<)、右移(>>)
位操作一般来说比加减乘除计算要快一些
与(&)操作符的位都为1时,才为1,其他都为0,因此与(&)操作符的结果范围在[0, Math.Min(x,y)],x,y均为正整数
或(|)操作符的位都为0时,才为0,其他都为1,因此或(|)操作符的结果范围在[Math.Max(x,y), x+y],x,y均为正整数
非(~)操作符按位取反,1转化为0, 0转化为1,因此非(~)操作符满足[x+~x=-1]一个数与其取反操作之和为-1
异或(^)操作符的位不同时为1, 位相同时为0
左移(<<)操作符:【最左侧位不要,在最右侧补0】,相当于乘以2个N次方,【移位是除以32后的余数,范围[0,31],即以32为一个周期】
右移(>>)操作符:【最右侧位不要,在最左侧补符号位。(正数补0,负数补1)】,相当于除以2个N次方,【移位是除以32后的余数,范围[0,31],即以32为一个周期】
相关测试程序如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Linq.Expressions;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace BitOperationDemo
- {
- class Program
- {
- /// <summary>
- /// 标识符字典
- /// </summary>
- static readonly Dictionary<OperationSymbol, string> dict = new Dictionary<OperationSymbol, string>()
- {
- { OperationSymbol.AND,"与(&)"},{ OperationSymbol.OR,"或(|)"},{ OperationSymbol.NOT,"非(~)"},{ OperationSymbol.XOR,"异或(^)"},
- { OperationSymbol.SHIFT_LEFT,"左移(<<)"},{ OperationSymbol.SHIFT_RIGHT,"右移(>>)"}
- };
- static void Main(string[] args)
- {
- Console.SetWindowSize(120, 50);
- Console.WriteLine($"与(&)操作符的位都为1时,才为1,其他都为0,因此与(&)操作符的结果范围在[0, Math.Min(x,y)],x,y均为正整数");
- Console.WriteLine($"或(|)操作符的位都为0时,才为0,其他都为1,因此或(|)操作符的结果范围在[Math.Max(x,y), x+y],x,y均为正整数");
- Console.WriteLine($"非(~)操作符按位取反,1转化为0, 0转化为1,因此非(~)操作符满足[x+~x=-1]一个数与其取反操作之和为-1");
- Console.WriteLine($"异或(^)操作符的位不同时为1, 位相同时为0");
- Console.WriteLine($"左移(<<)操作符:【最左侧位不要,在最右侧补0】,相当于乘以2个N次方,【移位是除以32后的余数,范围[0,31],即以32为一个周期】");
- Console.WriteLine($"右移(>>)操作符:【最右侧位不要,在最左侧补符号位。(正数补0,负数补1)】,相当于除以2个N次方,【移位是除以32后的余数,范围[0,31],即以32为一个周期】");
- Console.WriteLine();
- int x = 12345;
- int y = 34567;//34567除以32,余数为7,相当于移动7位
- string binaryX = Convert.ToString(x, 2).PadLeft(32, '0');
- string binaryY = Convert.ToString(y, 2).PadLeft(32, '0');
- Console.WriteLine($"整数【{x}】对应的32位二进制为【{binaryX}】");
- Console.WriteLine($"整数【{y}】对应的32位二进制为【{binaryY}】");
- Console.WriteLine("-----------------下面分别用二进制字符串逻辑处理 以及 系统内置的操作符进行操作计算-----------------");
-
- PrintOperatorResult(x, y, binaryX, binaryY, OperationSymbol.AND);
- PrintOperatorResult(x, y, binaryX, binaryY, OperationSymbol.OR);
- PrintOperatorResult(x, y, binaryX, binaryY, OperationSymbol.NOT);
- PrintOperatorResult(x, y, binaryX, binaryY, OperationSymbol.XOR);
- PrintOperatorResult(x, y, binaryX, binaryY, OperationSymbol.SHIFT_LEFT);
- PrintOperatorResult(x, y, binaryX, binaryY, OperationSymbol.SHIFT_RIGHT);
-
- Console.WriteLine("-----------------下面测试负数进行操作计算-----------------");
- x = -12345;
- binaryX = Convert.ToString(x, 2).PadLeft(32, '0');
- PrintOperatorResult(x, y, binaryX, binaryY, OperationSymbol.AND);
- PrintOperatorResult(x, y, binaryX, binaryY, OperationSymbol.OR);
- PrintOperatorResult(x, y, binaryX, binaryY, OperationSymbol.NOT);
- PrintOperatorResult(x, y, binaryX, binaryY, OperationSymbol.XOR);
- PrintOperatorResult(x, y, binaryX, binaryY, OperationSymbol.SHIFT_LEFT);
- PrintOperatorResult(x, y, binaryX, binaryY, OperationSymbol.SHIFT_RIGHT);
- Console.ReadLine();
- }
-
- /// <summary>
- /// 打印结果比较
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <param name="binaryX"></param>
- /// <param name="binaryY"></param>
- /// <param name="operationSymbol"></param>
- static void PrintOperatorResult(int x, int y, string binaryX, string binaryY, OperationSymbol operationSymbol)
- {
- string binaryResult = GetOperatorResult(binaryX, binaryY, operationSymbol);
- int result = 0;
- switch (operationSymbol)
- {
- case OperationSymbol.AND:
- result = x & y;
- break;
- case OperationSymbol.OR:
- result = x | y;
- break;
- case OperationSymbol.NOT:
- result = ~x;
- break;
- case OperationSymbol.XOR:
- result = x ^ y;
- break;
- case OperationSymbol.SHIFT_LEFT:
- result = x << y;
- break;
- case OperationSymbol.SHIFT_RIGHT:
- result = x >> y;
- break;
- }
- Console.WriteLine($"{dict[operationSymbol]}操作符系统内置的操作符运算结果为【{result}】,使用二进制字符串还原后的整数结果为【{Convert.ToInt32(binaryResult, 2)}】");
- Console.WriteLine();
- }
-
- /// <summary>
- /// 获取操作符的结果
- /// </summary>
- /// <param name="binaryX">32位二进制字符串,第一个数</param>
- /// <param name="binaryY">32位二进制字符串,第二个数</param>
- /// <param name="operationSymbol">指定的操作符枚举</param>
- /// <returns></returns>
- static string GetOperatorResult(string binaryX, string binaryY, OperationSymbol operationSymbol)
- {
- string result = string.Empty;
- switch (operationSymbol)
- {
- case OperationSymbol.AND:
- result = CalculateOperatorResult(binaryX, binaryY, (left, right) => (left == '1' && right == '1') ? "1" : "0");
- break;
- case OperationSymbol.OR:
- result = CalculateOperatorResult(binaryX, binaryY, (left, right) => (left == '0' && right == '0') ? "0" : "1");
- break;
- case OperationSymbol.NOT:
- result = CalculateOperatorResult(binaryX, binaryY, (left, right) => (left == '0') ? "1" : "0");
- break;
- case OperationSymbol.XOR:
- result = CalculateOperatorResult(binaryX, binaryY, (left, right) => (left == right) ? "0" : "1");
- break;
- case OperationSymbol.SHIFT_LEFT:
- result = CalculateShiftResult(binaryX, Convert.ToInt32(binaryY, 2), true);
- break;
- case OperationSymbol.SHIFT_RIGHT:
- result = CalculateShiftResult(binaryX, Convert.ToInt32(binaryY, 2), false);
- break;
- }
- Console.WriteLine($"{dict[operationSymbol]}操作符逻辑运算的32位二进制结果为【{result}】");
- return result;
- }
-
- /// <summary>
- /// 计算逻辑运算的结果【与,或,非,异或】
- /// </summary>
- /// <param name="binaryX">32位二进制字符串,第一个数</param>
- /// <param name="binaryY">32位二进制字符串,第二个数</param>
- /// <param name="logicOperator">逻辑操作委托</param>
- /// <returns></returns>
- static string CalculateOperatorResult(string binaryX, string binaryY, Func<char, char, string> logicOperator)
- {
- string result = string.Empty;
- for (int i = 0; i < 32; i++)
- {
- result += logicOperator(binaryX[i], binaryY[i]);
- }
- return result;
- }
-
- /// <summary>
- /// 计算移位操作【左移,右移】
- /// </summary>
- /// <param name="binaryX"></param>
- /// <param name="shiftCount">移动几位,该数需要转化为【除以32的余数】</param>
- /// <param name="leftShift">true代表左移,false代表右移</param>
- /// <returns></returns>
- static string CalculateShiftResult(string binaryX, int shiftCount, bool leftShift)
- {
- //比如移动32位,就相当于移动0位,移动33位,就相当于移动1位【32位作为一个周期】
- shiftCount = (int)((uint)shiftCount % 32U);//确保余数在0~31之间波动
- if (leftShift)
- {
- //左移:【最左侧位不要,在最右侧补0】
- return binaryX.Remove(0, shiftCount).PadRight(32, '0');
- }
- else
- {
- //右移:【最右侧位不要,在最左侧补符号位。(正数补0,负数补1)】
- return binaryX.Remove(32 - shiftCount, shiftCount).PadLeft(32, binaryX[0]);
- }
- }
- }
-
- /// <summary>
- /// 操作符号,运算符号
- /// </summary>
- enum OperationSymbol
- {
- /// <summary>
- /// 与 【位都是1时结果为1,否则为0】
- /// </summary>
- AND = 0,
- /// <summary>
- /// 或 【位都是0时结果为0,否则为1】
- /// </summary>
- OR = 1,
- /// <summary>
- /// 非 【位取反】,非操作只考虑第一个数
- /// </summary>
- NOT = 2,
- /// <summary>
- /// 异或 【位不同是为1,相同为0】
- /// </summary>
- XOR = 3,
- /// <summary>
- /// 左移,相当于乘以2个N次方【最左侧位不要,在最右侧补0】
- /// </summary>
- SHIFT_LEFT = 4,
- /// <summary>
- /// 右移,相当于除以2个N次方【最右侧位不要,在最左侧补符号位。(正数补0,负数补1)】
- /// </summary>
- SHIFT_RIGHT = 5
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。