C#的常見幾種位操作運(yùn)算,與($)、或(|)、非(~)、異或(^)、左移(<<)、右移(>>)
位操作一般來(lái)說(shuō)比加減乘除計(jì)算要快一些
與(&)操作符
與(&)操作符的位都為1時(shí),才為1,其他都為0,因此與(&)操作符的結(jié)果范圍在[0, Math.Min(x,y)],x,y均為正整數(shù)
或(|)操作符
或(|)操作符的位都為0時(shí),才為0,其他都為1,因此或(|)操作符的結(jié)果范圍在[Math.Max(x,y), x+y],x,y均為正整數(shù)
非(~)操作符
非(~)操作符按位取反,1轉(zhuǎn)化為0, 0轉(zhuǎn)化為1,因此非(~)操作符滿足[x+~x=-1]一個(gè)數(shù)與其取反操作之和為-1
異或(^)操作符
異或(^)操作符的位不同時(shí)為1, 位相同時(shí)為0
左移(<<)操作符
左移(<<)操作符:【最左側(cè)位不要,在最右側(cè)補(bǔ)0】,相當(dāng)于乘以2個(gè)N次方,【移位是除以32后的余數(shù),范圍[0,31],即以32為一個(gè)周期】
右移(>>)操作符
右移(>>)操作符:【最右側(cè)位不要,在最左側(cè)補(bǔ)符號(hào)位。(正數(shù)補(bǔ)0,負(fù)數(shù)補(bǔ)1)】,相當(dāng)于除以2個(gè)N次方,【移位是除以32后的余數(shù),范圍[0,31],即以32為一個(gè)周期】
C#新建控制臺(tái)應(yīng)用程序BitOperationDemo。
相關(guān)測(cè)試程序如下:
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>
/// 標(biāo)識(shí)符字典
/// </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時(shí),才為1,其他都為0,因此與(&)操作符的結(jié)果范圍在[0, Math.Min(x,y)],x,y均為正整數(shù)");
Console.WriteLine($"或(|)操作符的位都為0時(shí),才為0,其他都為1,因此或(|)操作符的結(jié)果范圍在[Math.Max(x,y), x+y],x,y均為正整數(shù)");
Console.WriteLine($"非(~)操作符按位取反,1轉(zhuǎn)化為0, 0轉(zhuǎn)化為1,因此非(~)操作符滿足[x+~x=-1]一個(gè)數(shù)與其取反操作之和為-1");
Console.WriteLine($"異或(^)操作符的位不同時(shí)為1, 位相同時(shí)為0");
Console.WriteLine($"左移(<<)操作符:【最左側(cè)位不要,在最右側(cè)補(bǔ)0】,相當(dāng)于乘以2個(gè)N次方,【移位是除以32后的余數(shù),范圍[0,31],即以32為一個(gè)周期】");
Console.WriteLine($"右移(>>)操作符:【最右側(cè)位不要,在最左側(cè)補(bǔ)符號(hào)位。(正數(shù)補(bǔ)0,負(fù)數(shù)補(bǔ)1)】,相當(dāng)于除以2個(gè)N次方,【移位是除以32后的余數(shù),范圍[0,31],即以32為一個(gè)周期】");
Console.WriteLine();
int x = 12345;
int y = 34567;//34567除以32,余數(shù)為7,相當(dāng)于移動(dòng)7位
string binaryX = Convert.ToString(x, 2).PadLeft(32, '0');
string binaryY = Convert.ToString(y, 2).PadLeft(32, '0');
Console.WriteLine($"整數(shù)【{x}】對(duì)應(yīng)的32位二進(jìn)制為【{binaryX}】");
Console.WriteLine($"整數(shù)【{y}】對(duì)應(yīng)的32位二進(jìn)制為【{binaryY}】");
Console.WriteLine("-----------------下面分別用二進(jìn)制字符串邏輯處理 以及 系統(tǒng)內(nèi)置的操作符進(jìn)行操作計(jì)算-----------------");
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("-----------------下面測(cè)試負(fù)數(shù)進(jìn)行操作計(jì)算-----------------");
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>
/// 打印結(jié)果比較
/// </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]}操作符系統(tǒng)內(nèi)置的操作符運(yùn)算結(jié)果為【{result}】,使用二進(jìn)制字符串還原后的整數(shù)結(jié)果為【{Convert.ToInt32(binaryResult, 2)}】");
Console.WriteLine();
}
/// <summary>
/// 獲取操作符的結(jié)果
/// </summary>
/// <param name="binaryX">32位二進(jìn)制字符串,第一個(gè)數(shù)</param>
/// <param name="binaryY">32位二進(jìn)制字符串,第二個(gè)數(shù)</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]}操作符邏輯運(yùn)算的32位二進(jìn)制結(jié)果為【{result}】");
return result;
}
/// <summary>
/// 計(jì)算邏輯運(yùn)算的結(jié)果【與,或,非,異或】
/// </summary>
/// <param name="binaryX">32位二進(jìn)制字符串,第一個(gè)數(shù)</param>
/// <param name="binaryY">32位二進(jìn)制字符串,第二個(gè)數(shù)</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>
/// 計(jì)算移位操作【左移,右移】
/// </summary>
/// <param name="binaryX"></param>
/// <param name="shiftCount">移動(dòng)幾位,該數(shù)需要轉(zhuǎn)化為【除以32的余數(shù)】</param>
/// <param name="leftShift">true代表左移,false代表右移</param>
/// <returns></returns>
static string CalculateShiftResult(string binaryX, int shiftCount, bool leftShift)
{
//比如移動(dòng)32位,就相當(dāng)于移動(dòng)0位,移動(dòng)33位,就相當(dāng)于移動(dòng)1位【32位作為一個(gè)周期】
shiftCount = (int)((uint)shiftCount % 32U);//確保余數(shù)在0~31之間波動(dòng)
if (leftShift)
{
//左移:【最左側(cè)位不要,在最右側(cè)補(bǔ)0】
return binaryX.Remove(0, shiftCount).PadRight(32, '0');
}
else
{
//右移:【最右側(cè)位不要,在最左側(cè)補(bǔ)符號(hào)位。(正數(shù)補(bǔ)0,負(fù)數(shù)補(bǔ)1)】
return binaryX.Remove(32 - shiftCount, shiftCount).PadLeft(32, binaryX[0]);
}
}
}
/// <summary>
/// 操作符號(hào),運(yùn)算符號(hào)
/// </summary>
enum OperationSymbol
{
/// <summary>
/// 與 【位都是1時(shí)結(jié)果為1,否則為0】
/// </summary>
AND = 0,
/// <summary>
/// 或 【位都是0時(shí)結(jié)果為0,否則為1】
/// </summary>
OR = 1,
/// <summary>
/// 非 【位取反】,非操作只考慮第一個(gè)數(shù)
/// </summary>
NOT = 2,
/// <summary>
/// 異或 【位不同是為1,相同為0】
/// </summary>
XOR = 3,
/// <summary>
/// 左移,相當(dāng)于乘以2個(gè)N次方【最左側(cè)位不要,在最右側(cè)補(bǔ)0】
/// </summary>
SHIFT_LEFT = 4,
/// <summary>
/// 右移,相當(dāng)于除以2個(gè)N次方【最右側(cè)位不要,在最左側(cè)補(bǔ)符號(hào)位。(正數(shù)補(bǔ)0,負(fù)數(shù)補(bǔ)1)】
/// </summary>
SHIFT_RIGHT = 5
}
}
程序運(yùn)行如圖:
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-602817.html
?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-602817.html
到了這里,關(guān)于C#的幾種位操作運(yùn)算,與、或、非、異或、左移、右移的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!