CS1L13——位运算符

位运算符

位运算符是用于二进制的对位运算,一个字节的表示格式是这样的:0000 0000

补充知识:反码与补码

内存内存储的二进制数都是补码,而首位数即符号位为0的是正数,为1的是负数

正数的负码和补码与原码都相同

负数的负码是在原码首位不变的情况下都取反,负数的补码是在负码的基础上+1
1111 1111 1111 1111 1111 1111 1111 1001 符号位是1,是负数,因此将补码-1还原为负码
1000 0000 0000 0000 0000 0000 0000 0110 => -6 将负码除符号位的每一位都取反,还原为原码,110 => 6 因此是-6

  1. 位与 &

    规则 连接两个数值进行对位运算 将数值转为二进制
    对位运算 有0则0

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    int a = 1;  //001
    int b = 5; //101
    // 001
    //& 101
    // 001 = 1
    int c = a & b;
    Console.WriteLine(c); //1

    a = 3; //00011
    b = 19; //10011
    // 00011
    //& 10011
    // 00011
    c = a & b;
    Console.WriteLine(c); //3

    a = 1; //00001
    b = 5; //00101
    c = 19; //10011
    // 00001
    //& 00101
    // 00001
    //& 10011
    // 00001
    int d = a & b & c;
    Console.WriteLine(d); //1

    输出:

    1
    2
    3
    1
    3
    1

    可见,位与&​最终会使结果和最小的数一样或者更小

  2. 位或 |

    规则 连接两个数值进行对位运算 将数值转为二进制
    对位运算 有1则1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    a = 1;  //001
    b = 5; //101
    // 001
    //| 101
    // 101
    c = a | b;
    Console.WriteLine(c); //5

    a = 5; //00101
    b = 10; //01010
    c = 20; //10100
    // 00101
    //| 01010
    // 01111
    //| 10100
    // 11111
    d = a | b | c;
    Console.WriteLine(d); //31

    输出:

    1
    2
    5
    31
  3. 异或 ^

    规则 连接两个数值进行对位运算 将数值转为二进制
    对位运算 相同为0 不同为1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    a = 1;  //001
    b = 5; //101
    // 001
    //^ 101
    // 100
    c = a ^ b;
    Console.WriteLine(c);

    ## 4
    a = 10; // 1010
    b = 11; // 1011
    c = 4; // 0100
    // 1010
    //^ 1011
    // 0001
    //^ 0100
    // 0101
    Console.WriteLine(a ^ b ^ c);

    ## 5
  4. 位取反 ~

    规则 写在数值前面 将数值转为二进制
    对位运算 0变1 1变0

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    a = 5;  //0000 0000 0000 0000 0000 0000 0000 0101
    //数值长度取决于变量类型的位数,例如int类型占32位,因此有32个位数
    //~ 0000 0000 0000 0000 0000 0000 0000 0101
    // 1111 1111 1111 1111 1111 1111 1111 1010
    //注意:内存内存储的二进制数都是补码,而首位数即符号位为0的是正数,为1的是负数
    //正数的负码和补码与原码都相同
    //负数的负码是在原码首位不变的情况下都取反,负数的补码是在负码的基础上+1
    // 1111 1111 1111 1111 1111 1111 1111 1001 符号位是1,是负数,因此将补码-1还原为负码
    // 1000 0000 0000 0000 0000 0000 0000 0110 => -6 将负码除符号位的每一位都取反,还原为原码,110 => 6 因此是-6
    Console.WriteLine(~a);

    输出:

    1
    -6
  5. 左移<< 和 右移>>

    规则 让一个数的二进制进行左移和右移
    左移几位 右侧加几个0

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    a = 5;  // 101
    c = a << 5;
    //1 1010
    //2 10100
    //3 101000
    //4 1010000
    //5 10100000 = 32 + 128 = 160
    Console.WriteLine(c); //160

    // 右移几位右侧去掉几个数
    a = 19; // 10011
    c = a >> 2;
    //0 10011
    //1 01001
    //2 00100 = 4
    Console.WriteLine(c); //4

    输出:

    1
    2
    160
    4

本课源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
namespace lesson13位运算符
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("位运算符");
#region 位与 &
// 规则 连接两个数值进行对位运算 将数值转为二进制
// 对位运算 有0则0
int a = 1; //001
int b = 5; //101
// 001
//& 101
// 001 = 1
int c = a & b;
Console.WriteLine(c);

a = 3; // 00011
b = 19; // 10011
// 00011
//& 10011
// 00011
c = a & b;
Console.WriteLine(c);

a = 1; //00001
b = 5; //00101
c = 19; //10011
// 00001
//& 00101
// 00001
//& 10011
// 00001
int d = a & b & c;
Console.WriteLine(d);
//可见,位与&最终会使结果和最小的数一样或者更小
#endregion

#region 位或 |
// 规则 连接两个数值进行对位运算 将数值转为二进制
// 对位运算 有1则1

a = 1; //001
b = 5; //101
// 001
//| 101
// 101
c = a | b;
Console.WriteLine(c);

a = 5; //00101
b = 10; //01010
c = 20; //10100
// 00101
//| 01010
// 01111
//| 10100
// 11111
d = a | b | c;
Console.WriteLine(d);
#endregion

#region 异或 ^
// 规则 连接两个数值进行对位运算 将数值转为二进制
// 对位运算 相同为0 不同为1
a = 1; //001
b = 5; //101
// 001
//^ 101
// 100
c = a ^ b;
Console.WriteLine(c);

a = 10; // 1010
b = 11; // 1011
c = 4; // 0100
// 1010
//^ 1011
// 0001
//^ 0100
// 0101
Console.WriteLine(a ^ b ^ c);
#endregion

#region 位取反 ~
// 规则 写在数值前面 将数值转为二进制
// 对位运算 0变1 1变0
a = 5; //0000 0000 0000 0000 0000 0000 0000 0101
//数值长度取决于变量类型的位数,例如int类型占32位,因此有32个位数
//~ 0000 0000 0000 0000 0000 0000 0000 0101
// 1111 1111 1111 1111 1111 1111 1111 1010
//注意:内存内存储的二进制数都是补码,而首位数即符号位为0的是正数,为1的是负数
//正数的负码和补码与原码都相同
//负数的负码是在原码首位不变的情况下都取反,负数的补码是在负码的基础上+1
// 1111 1111 1111 1111 1111 1111 1111 1001 符号位是1,是负数,因此将补码-1还原为负码
// 1000 0000 0000 0000 0000 0000 0000 0110 => -6 将负码除符号位的每一位都取反,还原为原码,110 => 6 因此是-6
Console.WriteLine(~a);
#endregion

#region 左移<< 和 右移>>
// 规则 让一个数的二进制进行左移和右移
// 左移几位 右侧加几个0
a = 5; // 101
c = a << 5;
//1 1010
//2 10100
//3 101000
//4 1010000
//5 10100000 = 32 + 128 = 160
Console.WriteLine(c);

// 右移几位右侧去掉几个数
a = 19; // 10011
c = a >> 2;
//0 10011
//1 01001
//2 00100 = 4
Console.WriteLine(c);
#endregion
}
}
}