- 一.计算机进制
- 1. 十进制 :范围 0-9
- 2. 二进制:这玩意就是计算机使用的进制方式, 范围只有0和1,满2进1,例如:
- 3. 八进制:范围0-7,满8进1, 以数字0开头表示,例如 :
- 4. 十六进制:范围 0-9及A-F(a-f), 满16进1,以0x或0X开头表示
- 5. 进制对照图
- 二.各种进制之间的转换
- 1. 各种进制 转 十进制
- 2. 十进制 转 各种进制
- 3. 二进制 转 各种进制
- 4. 各种进制 转 二进制
- 三.原码,反码,补码
- 四.golang位运算
- 1. 三种位运算:
- 2. 两种移位运算符:
说起位运算,那得先说原码反码补码。
说起原码反码补码,那得先说计算机进制…
算了,我们就从头来,一次撸透这兄弟几个!
一.计算机进制 1. 十进制 :范围 0-9
就是我们日常使用的进制方式,数字范围0-19,满10进1,就是说呢,10+1=11, 这个大家都懂就不详细举例了哈。
var num int = 3
fmt.Printf("num的十进制:%dn", num) //打印3
2. 二进制:这玩意就是计算机使用的进制方式, 范围只有0和1,满2进1,例如:
0000 0000 + 1 = 0000 0001 0000 0001 + 1 = 0000 0010 0000 0010 + 1 = 0000 0011 0000 0011 + 1 = 0000 0100 最后一位进1等于0 最后一位进的1加在倒数第二位 倒数第二位的1又进1等于0,把进的位加在倒数第3位 倒数第三位就等于了1 以此类推......
var num int = 3 // 十进制的数字 3
fmt.Printf("num的二进制:%bn", num) // 打印11, 具体请看本文的进制对照图
3. 八进制:范围0-7,满8进1, 以数字0开头表示,例如 :
var n1 int = 7 // 十进制的数字 7
fmt.Printf("7的八进制:%on", n1) // 打印7
var n2 int = 9 // 十进制的数字 9
fmt.Printf("9的八进制:%on", n2) // 打印11
4. 十六进制:范围 0-9及A-F(a-f), 满16进1,以0x或0X开头表示
0-9对应十进制的0-9,
A-F对应十进制的10-15
var n1 int = 10
fmt.Printf("10的十六进制:%Xn", n1) // 打印A
var n2 int = 12
fmt.Printf("12的十六进制:%Xn", n2) // 打印C
var n3 int = 15
fmt.Printf("15的十六进制:%Xn", n3) // 打印F
var n4 int = 16
fmt.Printf("16的十六进制:%Xn", n4) // 打印10, 满16进1
5. 进制对照图
| 十进制 | 二进制 | 十六进制 | 八进制 |
|---|---|---|---|
| 0 | 0000 0000 | 0 | 0 |
| 1 | 0000 0001 | 1 | 1 |
| 2 | 0000 0010 | 2 | 2 |
| 3 | 0000 0011 | 3 | 3 |
| 4 | 0000 0100 | 4 | 4 |
| 5 | 0000 0101 | 5 | 5 |
| 6 | 0000 0110 | 6 | 6 |
| 7 | 0000 0111 | 7 | 7 |
| 8 | 0000 1000 | 8 | 10 |
| 9 | 0000 1001 | 9 | 11 |
| 10 | 0000 1010 | A | 12 |
| 11 | 0000 1011 | B | 13 |
| 12 | 0000 1100 | C | 14 |
| 13 | 0000 1101 | D | 15 |
| 14 | 0000 1110 | E | 16 |
| 15 | 0000 1111 | F | 17 |
| 16 | 0001 0000 | 10 | 20 |
| 17 | 0001 0001 | 11 | 21 |
| 以此类推 | … | … | … |
二.各种进制之间的转换 1. 各种进制 转 十进制
-
二进制转十进制
方法:从二进制的最低位(最右边的那一位)开始,最低位看作第一位,依次往左把每一位的数拿出来,乘2的位数-1次方,然后求和。
例:把二进制1110转为十进制
2的1-1次方 = 1
2的2-1次方 = 2
2的3-1次方 = 4
2的4-1次方 = 8
1110 => (0 * 2^0) + (1 * 2^1) + (1 * 2^2) + (1 * 2^3)
1110 => (0 * 1) + (1 * 2) + (1 * 4) + (1 * 8) => 0 + 2 + 4 + 8 = 14 -
八进制转十进制
方法:从八进制的最低位(最右边的那一位)开始,最低位看作第一位,依次往左把每一位的数拿出来,乘8的位数-1次方,然后求和。
例:把八进制0123转为十进制
0123 => (3 * 8^0) + (2 * 8^1) + (1 * 8^2) + (0 * 8^3)
0123 => (3 * 1) + (2 * 8) + (1 * 64) + (0 * 512) => 3 + 16 + 64 + 0 = 83 -
十六进制转十进制
方法:从十六进制的最低位(最右边的那一位)开始,最低位看作第一位,依次往左把每一位的数拿出来,乘16的位数-1次方,然后求和。
例:把十六进制0x25C(就是25C)转为十进制
25C => (12 * 16^0) + (5 * 16^1) + (2 * 16^2)
0123 => (12 * 1) + (5 * 16) + (2 * 256) => 12 + 80 + 512 = 604
-
十进制转二进制
方法:把十进制数一直除2,知道商为0为止,把每一次除完之后的余数反过来拼在一起,就是它对应的二进制数
例:把十进制数67转二进制
所以十进制67 => 二进制1000011 -
十进制转八进制
方法:把十进制数一直除8,知道商为0为止,把每一次除完之后的余数反过来拼在一起,就是它对应的八进制数
例:把十进制数157转八进制
所以十进制157 => 八进制235 -
十进制转十六进制
方法:把十进制数一直除16,知道商为0为止,把每一次除完之后的余数反过来拼在一起,就是它对应的十六进制数
例:把十进制数367转十六进制
所以十进制367 => 十六进制16F
-
二进制转八进制
方法:从最低位开始,把每3个二进制数编队为一组,不够的补0,每组进行转化为八进制
例:把二进制 11010101 转为 八进制
先转十进制:011 => 3, 010 => 2, 101 => 5
11010101 编组之后 (011)(010)(101) =>八进制 325 -
二进制转十六进制
方法:从最低位开始,把每4个二进制数编队为一组,不够的补0,每组进行转化为十六进制
例:把二进制 11010101 转为 十六进制
先转十进制:1101 => 13, 0101 => 5
11010101 编组之后 (1101)(0101) =>十六进制 D5
-
八进制转二进制
方法:把八进制的每一位数,转化为对应3位的二进制数, 不够的补0,或者不用补,自己看得出来也行
例:把八进制 325 转为二进制
3 => 二进制 011
2 => 二进制 010
5 => 二进制 101
所以:325 =>二进制 11010101 -
十六进制转二进制
方法:把十六进制的每一位数,转化为对应4位的二进制数, 不够的补0,或者不用补,自己看得出来也行
例:把十六进制0xD5 转为 二进制
D => 十进制 13 => 二进制 1101
5 => 二进制 0101
所以:D5 => 二进制 11010101
众所周知,1个字节=8位,即 0000 0000 - 1111 1111。
当一个字节为 1111 1111 :表示的数字是 255.
当一个字节为 0000 0000 :表示的数字是0.
所以一个字节可以存储0~255范围内的数字,总共256个值,负数的话可以存储 -128 ~ +127范围内的数值。
但是负数怎么表示呢?
所以原码,反码,补码就出来了:
| 类型 | 说明 | 存储范围 |
|---|---|---|
| 原码 | 第一位为符号位,0代表正,1代表负,剩下7位表示数字本身 | -127 ~ +127 |
| 反码 | 正数反码与原码一致,负数反码 按照原码 按位取反,第一个符号位不变 | -127 ~ +127 |
| 补码 | 正数补码与原码一致,负数补码是该数反码+1 | -128 ~ +127 |
原码和反码 : 第一位用来表示符号位,所以少了一位。
补码 : 第一位既表示符号,也表示数值范围
例如:
| 数字 | 5 | -5 | -128 |
|---|---|---|---|
| 原码 | 0000 0101 | 1000 0101 | 表示不了 |
| 反码 | 0000 0101 | 1111 1010 | 表示不了 |
| 补码 | 0000 0101 | 1111 1011 | 1000 0000 |
总结:
1.正数的原码,反码,补码都是一样的。
2.0的反码和补码都是0。
3.计算机都是以补码的方式进行计算的。
- 为啥计算机以补码来运算呢?
因为补码可以在不缺少位的情况下表示负数,例如 1-1在计算机内运算的时候其实是 1+(-1)
快了快了,最后亿个知识点了,肝起来朋友们!
1. 三种位运算:| 符号 | 运算规则 |
|---|---|
| 按位与 & | 二进制中比较的两位,都是1,结果为1,否则为0 |
| 按位或 | | 二进制中比较的两位,其中有一个是1,结果为1,否则为0 |
| 按位异或 ^ | 二进制中比较的两位,一位为0另一位为1,结果为1,否则为0 |
例1:
2&3 (正数的原码,反码,补码都一样) 2的原码 => 0000 0010 2的反码 => 0000 0010 2的补码 => 0000 0010 3的原码 => 0000 0011 3的反码 => 0000 0011 3的补码 => 0000 0011 因为计算机都是以补码方式来计算的 2&3 => 2的补码 0000 0010 & 3的补码 0000 0011 ---------------- 算出补码 0000 0010 =>十进制 2 所以 2&3 = 2
例2:
2|3 (正数的原码,反码,补码都一样) 2|3 => 2的补码 0000 0010 | 3的补码 0000 0011 ---------------- 算出补码 0000 0011 =>十进制 3 所以 2|3 = 3
例3:
2 ^ 3 (正数的原码,反码,补码都一样) 2 ^ 3 => 2的补码 0000 0010 ^ 3的补码 0000 0011 ---------------- 算出补码 0000 0001 =>十进制 1 所以 2 ^ 3 = 1
来一个麻烦的,负数
例4:
-2^2 -2的原码 => 1000 0010 -2的反码 => 1111 1101 -2的补码 => 1111 1110 -2^2 => -2的补码 1111 1110 ^ 2的补码 0000 0010 ---------------- 算出补码 1111 1100 减1位=> 反码1111 1011 符号为不变按位取反=> 原码1000 0100 =>十进制 -4 所以 -2^2 = -42. 两种移位运算符:
同样是以补码方式进行运算
| 符号 | 运算规则 |
|---|---|
| 右移 >> | 二进制中底位溢出,符号为不变,用符号位补溢出的高位 |
| 左移 << | 二进制中符号位不变,低位补0 |
例1:
1 >> 2 右移2位 1的补码 0000 0001 低位向右溢出两位, 最后的两位01溢出了, 再用符号位补溢出高位 所以 1 >> 2 => 0000 0001 >> 2 => 0000 0000 =>十进制 0
例2:
1 << 2 左移2位 1的补码 0000 0001 符号位不变, 低位补0 所以 1 << 2 => 0000 0001 << 2 => 0000 0100 =>十进制 4
打完收工,朋友们学费了吗!



