位运算符包括:| 按位或 OR,& 按位与 AND,^ 按位异或 XOR,~ 取反 NOT,<< 左移 Left Shift,>> 右移 Right Shift,等等。本篇体验位运算符在C#中的应用。主要包括:

进制转换
    ※ 十进制转换成二进制
    ※ 二进制转换成十进制
| 按位或操作符
& 按位与操作符
^ 按位异或操作符
    ※ 使用^按位异或交换2个数
    ※ 使用^按位异或进行加密运算
~ 取反操作符
x << n 左移运算符
x >> n 右移运算符

进制转换

因为位运算是在二进制基础上进行的,所以进制转换是位运算的前提。

□ 十进制转换成二进制

比如,把10进制的数783转换成二进制,经过下面10个步骤。


把余数从下到上拼接起来,就是783的二进制,即1100001111。

在C#中,如果是Int16类型,意味着有16位整型数。对于783来说,如果表示成Int16类型,不足16位的话,要在前面补0,即要在1100001111补6个0,完整的表示是:0000001100001111。同样的道理,如果是Int32类型,意味着有32位整型数。

如何把-783转换成Int16类型的二进制呢?

→我们知道正数783表示成Int16类型的二进制是:0000001100001111
→在每个位置上倒转,即如果是1就变成0,反之亦然,倒转后变成:1111110011110000
→再加上1,变成:1111110011110001

□二进制转换成十进制

比如,把Int16类型的二进制数0000000100010110转换成十进制,经过下面的16个步骤。

从右向左,依次乘以2的n次方。

把所有的结果加起来:
0 + 2 + 4 + 0 + 16 + 0 + 0 + 0 + 256 + 0 = 2 + 4 + 16 + 256 = 278
所以,0000000100010110的十进制数是278。

如何把一个Int16类型的负二进制数转换成十进制呢?

比如有这样的一个二进制数:1111111111010011(Int16类型,第一位是数字1表示负数,第一位是数字0表示正数)
→每个位置上反转变成:0000000000101100
→进过计算,得到的十进制数是:44
→再加1,得到:45
→再变成负数,得到:-45

| 按位或操作符

假设,十进制数38和53进行按位或计算。
→经过计算,十进制数38的二进制表达是00100110,十进制数538的二进制表达是00110101。
→对| 按位或操作符来说,只要对应的二个二进位有一个为1时,结果就为1。

→把得到的00110111转换成十进制就是:55

如果用C#表示就是:

byte result = 38 | 53;

& 按位与操作符

假设,十进制数76和231进行按位与计算。
→经过计算,十进制数76的二进制表达是01001100,十进制数231的二进制表达是11100111。
→对& 按位与操作符来说,只要对应的二个二进位有一个为0时,结果就为0。

→把得到的 01000100转换成十进制就是:68

如果用C#表示就是:

byte result = 76 & 231;

^ 按位异或操作符

假设,十进制数138和43进行按位与计算。
→经过计算,十进制数138的二进制表达是10001010,十进制数43的二进制表达是00101011。
→对^ 按位异或操作符来说,当两对应的二进位相异时,结果为1。

→把得到的10100001转换成十进制就是:161

如果用C#表示就是:

byte result = 138 ^ 43 ;

□ 例子1:使用^ 按位异或交换2个数

int x = 4;
int y = 6;
x ^= y;
y ^= x;
x ^= y;
Console.WriteLine(x); //6
Console.WriteLine(y); //4

以上过程是这样的:
(1)x ^= y,相当于x = x ^ y
x的二进制是:00100
y的二进制是:00110
x和y进行异或,结果是:00010
x转换成十进制后,x为:2

(2)y ^= x,相当于y = y ^ x
y的二进制是:00110
x的二进制是:00010
y和x进行异或,结果是:00100
y转换成十进制后,y为:4

(3)x ^= y,相当于x = x ^ y
x的二进制是:00010
y的二进制是:00100
x和y进行异或,结果是:00110
x转换成十进制后,x为:6

□ 例子2:使用^按位异或进行加密运算

string msg = "这是我要加密的string字符串";
string k = "mypassword";
for(int i = 0; i < msg.Length; i++)
{
    sb.Append((char)(msg[i] ^ k[i % k.Length]));
}
Console.WriteLine(sb.ToString());

~ 取反操作符

假设,十进制数52进行取反计算。
→经过计算,十进制数52的二进制表达是00110100
→对~ 取反操作符来说,对应的二进位数按位求反,0变成1,1变成0

→把得到的11001011转换成十进制就是:203

如果用C#表示就是:

byte result = ~52;

x << n 左移运算符

每位向左移动n位,右边空缺的位置补0。
假设,十进制数154进行左移。

如果用C#表示就是:

byte b1 = 154;
byte b2 = (byte)b1 << 1;
Console.Writeline(b2);//结果是52,二进制是00110100

x >> n 右移运算符

每位向右移动n位,左边空缺的位置补0。
假设,十进制数155进行右移。

如果用C#表示就是:

byte b1 = 155;
byte b2 = (byte)(b1 >> 1);
Console.WriteLine(b2); // 结果: 77

总结:
| 按位或操作符来说,只要对应的二个二进位有一个为1时,结果就为1
& 按位与操作符来说,只要对应的二个二进位有一个为0时,结果就为0
^ 按位异或操作符来说,当两对应的二进位相异时,结果为1
~ 取反操作符来说,对应的二进位数按位求反,0变成1,1变成0
x << n 左移运算符,每位向左移动n位,右边空缺的位置补0
x >> n 右移运算符,每位向右移动n位,左边空缺的位置补0

参考资料:
Swapping of variables without Third Variable using XOR Logic
Understand how bitwise operators work
http://baike.baidu.com/view/9895739.htm?fr=aladdin

C#位运算符的基本用法的更多相关文章

  1. 位运算符的用法 ----非(!),与(&),或(|),异或(^)

    位运算符的用法 ----非(!),与(&),或(|),异或(^) 三种运算符均针对二进制 非!:是一元运算符.对一个二进制的整数按位取反,输入0则输出1,输入1则输出0. 例: 0100 -( ...

  2. PHP中的运算符---位运算符、递增递减运算符、三元运算符、字符串运算符、数组运算符、类型运算符、错误控制运算符

    1.位运算符 位运算符用来对整型数的指定位进行置位,如果被操作数是字符串,则对该字符串的ASCII码值进行操作. 运算类型 运算符 举例 结果 按位与 & $a & $b 将$a 与 ...

  3. ECMAScript 位运算符

    位运算符是在数字底层(即表示数字的 32 个数位)进行操作的. 重温整数 ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript ...

  4. C/C++ 位运算符

    C/C++位操作运算符 操作符 功能 用法 ~ 位求反 ~expr << 左移 expr1 << expr2 >> 右移 expr1 >> expr2 ...

  5. C语言--位运算符

    一.位运算符 1.按位与:& 1> 功能 * 只有对应的两个二进制位为1时,结果位才为1,否则为0 * 举例:10用二进制表示为1010,  7用二进制表示为0111.对两个数值进行&a ...

  6. Javascript中的位运算符和技巧

    ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript 中,所有整数字面量默认都是有符号整数,这意味着什么呢? 有符号整数使用 3 ...

  7. js 位运算符

    MDN定义:位运算符将它的操作数视为32位元的二进制串(0和1组成)而非十进制八进制或十六进制数. 例如:十进制数字9用二进制表示为1001,位运算符就是在这个二进制表示上执行运算,但是返回结果是标准 ...

  8. JavaScript位运算符

    位运算符是在数字底层(即表示数字的 32 个数位)进行操作的. 重温整数 ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript ...

  9. Java基础-位运算符Bitwise Operators

    Java基础-位运算符Bitwise Operators 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.位运算特点 位运算符分为按位与(&),按位或(|),按位异或(^ ...

随机推荐

  1. CxGrid 表格标题头居中

    选中这些列后 搞.

  2. 打印数据的字节(十六进制)表示-c语言代码

    先取数据地址,转换成单字节长度的类型(unsigned char)的指针,然后按照十六进制逐字节打印即可,格式为“%.2x”. sizeof()函数获取数据的字节数. /* $begin show-b ...

  3. C#连接mariadb代码及方式

    不负责任的说MariaDb和MySQL很多都是通用的,因为来自同一个爹... 和MySQL连接方式差不多 首先配置好你的MariaDb,创建test数据库,在test里创建MyTable表,脚本如下( ...

  4. gcc中C++一个特别的头文件

    今天在一段程序中看到这样一个很奇怪的语句: #include<bits/stdc++.h> 博主查了之后发现业界称其万能头文件,这个头文件包含了如下等头文件,几乎包含了所有的C++标准库头 ...

  5. Python djangorestframework安装库报错SSL: CERTIFICATE_VERIFY_FAILED

    Python djangorestframework 安装库报错SSL: CERTIFICATE_VERIFY_FAILED 问题描述 使用pip按照virtualenv报错,如下: pip inst ...

  6. shuffle过程分析

    shuffle的过程分析 shuffle阶段其实就是之前<MapReduce的原理及执行过程>中的步骤2.1.多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点 ...

  7. Java去重字符串的两种方法以及java中冒号的使用

    package com.removesamestring; import java.io.BufferedWriter; import java.util.ArrayList; import java ...

  8. Ionic实战五:ionic图表源码基于highcharts

    ionic图表demo基于Highcharts,highcharts 是一个用纯JavaScript编写的一个图表库, 能够很简单便捷的在web网站或是web应用程序添加有交互性的图表.HighCha ...

  9. CentOS 编译源码安装MySQL-5.6.16

    mysql5.6.16的安装和之前的5.5.5.1有些不同,编译的时候不再使用./configure来进行了,使用了cmake命令来进行编译项目. 1.准备编译环境 yum -y installmak ...

  10. Tensorflow学习:(一)tensorflow框架基本概念

    一.Tensorflow基本概念 1.使用图(graphs)来表示计算任务,用于搭建神经网络的计算过程,但其只搭建网络,不计算 2.在被称之为会话(Session)的上下文(context)中执行图 ...