23 Go原码、反码、补码及位运算详解

什么是原码、反码、补码
原码、反码、补码是计算机的二进制表示码
1 二进制的最高位是符号位,0表示正数,1表示负数
例如:1 的二进制表示为 0000 0001;-1 的二进制表示为 1000 0001

2 正数的原码、反码、补码都一样
3 负数的反码等于他的原码符号位不变,其他位取反
4 负数的补码等于他的反码+1
例如:
 1 -> 原码:0000 0001;反码:0000 0001;补码:0000 0001;
-1 -> 原码:1000 0001;反码:1111 1110;补码:1111 1111;

5 数字0的反码、补码都是0
6 计算机在运算的时候,都是以补码的方式来运算的
 
 
既然知道运算的时候都是以补码方式运算,那么就好理解位运算了
golang中有两个移位运算:左移位 << 和 右移位 >>
直接上代码:
 1 // golang中有两个移位运算:左移位 << 和 右移位 >>
 2 // 左移位 << :符号位不变,其他位整体左移,超出位数溢出截断,空缺的低位补0
 3 // 右移位 >> :符号位不变,其他位整体右移,超出位数溢出截断,并用符号位补空缺的高位
 4 var num int8 = 3
 5 var move int8 = 1
 6 var result int8 = num << move
 7 var operator string = "3 << 1"
 8 str := `计算3 << 1
 9 3的补码为 0000 0011
10 左移1位为 0000 0110
11 相当于3 * 2的1次方
12 转化为十进制为:6
13 `
14 fmt.Println(str)
15 fmt.Printf("原数字为%d,二进制为%b,%s计算后为 %d ,其二进制数为 %b \n", num, num, operator, result, result) // 原数字为3,二进制为11,2 << 2计算后为 6 ,其二进制数为 110
16 
17 num = -1
18 move = 2
19 result = num << move
20 operator = "-1 << 2"
21 str = `计算-1 << 2
22 -1的原码为 1000 0001
23 -1的反码为 1111 1110
24 -1的补码为 1111 1111
25 左移2位为 1111 1100
26 相当于-1 * 2的2次方
27 转化为十进制为:-4
28 上面位移运算后的二进制码为-4的补码,则
29 -4的补码为 1111 1100
30 -4的反码为补码减1 1111 1011
31 -4的原码为反码符号位不变其他位取反 1000 0100
32 `
33 fmt.Println(str)
34 fmt.Printf("原数字为%d,二进制为%b,%s计算后为 %d ,其二进制数为 %b \n", num, num, operator, result, result) // 原数字为-1,二进制为-1,-1 << 2计算后为 -4 ,其二进制数为 -100
35 
36 num = 3
37 move = 1
38 result = num >> move
39 operator = "3 >> 1"
40 str = `计算3 << 1
41 3的补码为 0000 0011
42 右移1位后高位用符号位补齐为 0000 0001
43 相当于3 / 2的1次方后取整
44 转化为十进制为:1
45 `
46 fmt.Println(str)
47 fmt.Printf("原数字为%d,二进制为%b,%s计算后为 %d ,其二进制数为 %b \n", num, num, operator, result, result) // 原数字为3,二进制为11,3 >> 1计算后为 1 ,其二进制数为 1
48 
49 num = -1
50 move = 2
51 result = num >> move
52 operator = "-1 >> 2"
53 str = `计算-1 >> 2
54 -1的原码为 1000 0001
55 -1的反码为 1111 1110
56 -1的补码为 1111 1111
57 右移2位后,高位缺位用符号位补齐为 1111 1111
58 相当于-1 / 2的2次方
59 转化为十进制为:-1
60 上面位移运算后的二进制码为-1的补码,则
61 -1的补码为 1111 1111
62 -1的反码为补码减1 1111 1110
63 -1的原码为反码符号位不变其他位取反 1000 0001
64 `
65 fmt.Println(str)
66 fmt.Printf("原数字为%d,二进制为%b,%s计算后为 %d ,其二进制数为 %b \n", num, num, operator, result, result) // 原数字为-1,二进制为-1,-1 >> 2计算后为 -1 ,其二进制数为 -1

 

 

 

Golang与、或、异或位运算符
& 与运算,两个数二进制相同位上数字都为1才得1
| 或运算,两个数二进制相同位上数字有一个为1就得1
^ 异或运算,两个数二进制相同位上数字不等才得1
 
纸上得来终觉浅,直接上代码
 1 var num1 int8 = 2
 2 var num2 int8 = 3
 3 var res int8 = num1 & num2
 4 var ope string = "2 & 3"
 5 str = `计算2 & 3
 6 2的补码为 0000 0010
 7 3的补码为 0000 0011
 8 2与3运算得0000 0010
 9 转化为十进制为:2
10 `
11 fmt.Println(str)
12 fmt.Printf("原数字为%d和%d,%s计算后为 %d ,其二进制数为 %b \n", num1, num2, ope, res, res) // 原数字为2和3,2 & 3计算后为 2 ,其二进制数为 10
13 
14 res = num1 | num2
15 ope = "2 | 3"
16 str = `计算2 | 3
17 2的补码为 0000 0010
18 3的补码为 0000 0011
19 2或3运算得0000 0011
20 转化为十进制为:3
21 `
22 fmt.Println(str)
23 fmt.Printf("原数字为%d和%d,%s计算后为 %d ,其二进制数为 %b \n", num1, num2, ope, res, res) // 原数字为2和3,2 | 3计算后为 3 ,其二进制数为 11
24 
25 res = num1 ^ num2
26 ope = "2 ^ 3"
27 str = `计算2 ^ 3
28 2的补码为 0000 0010
29 3的补码为 0000 0011
30 2异或3运算得0000 0001
31 转化为十进制为:1
32 `
33 fmt.Println(str)
34 fmt.Printf("原数字为%d和%d,%s计算后为 %d ,其二进制数为 %b \n", num1, num2, ope, res, res) // 原数字为2和3,2 ^ 3计算后为 1 ,其二进制数为 1
35 
36 num1 = -2
37 num2 = 2
38 res = num1 ^ num2
39 ope = "-2 ^ 2"
40 str = `计算-2 ^ 2
41 -2的原码为 1000 0010
42 -2的反码为 1111 1101
43 -2的补码为 1111 1110
44 2的补码为 0000 0010
45 -2异或2运算得1111 1100
46 1111 1100为补码
47 减1转化为反码为 1111 1011
48 反码除符号位取反得到原码 1000 0100
49 转化为十进制为:-4
50 `
51 fmt.Println(str)
52 fmt.Printf("原数字为%d和%d,%s计算后为 %d ,其二进制数为 %b \n", num1, num2, ope, res, res) // 原数字为-2和2,-2 ^ 2计算后为 -4 ,其二进制数为 -100

 

 

 
posted @ 2022-06-19 22:02  风铃如沧海  阅读(562)  评论(0编辑  收藏  举报