进制:
对于整数, 4 种表示方式
1、二进制:0,1 满2进1
2、十进制:0-9 满10进1
3、八进制:0-7 满8进1 以数字 0 开头表示
4、十六进制:0-9 及 A-F, 满16进1, 以0x 或者 0X 开头表示
此处的 A-F 不区分大小写 : 如 0x21AF + 1 = 0X21B0
进制图示:
十进制 | 十六进制 | 八进制 | 二进制 |
---|---|---|---|
0 | 0 | 0 | 0 |
1 | 1 | 1 | 1 |
2 | 2 | 2 | 10 |
3 | 3 | 3 | 11 |
4 | 4 | 4 | 100 |
5 | 5 | 5 | 101 |
6 | 6 | 6 | 110 |
7 | 7 | 7 | 111 |
8 | 8 | 10 | 1000 |
9 | 9 | 11 | 1001 |
10 | A | 12 | 1010 |
11 | B | 13 | 1011 |
12 | C | 14 | 1100 |
13 | D | 15 | 1101 |
14 | E | 16 | 1110 |
15 | F | 17 | 1111 |
16 | 10 | 20 | 10000 |
17 | 11 | 21 | 10001 |
[ 其他进制 => 二进制 ]
1、二进制转十进制
规则:从 最低位 开始( 右边的 ),将每个位上的数提取出来,乘以 2 的( 位数-1 )次方然后求和
// 1011 转 10进制
=12^(4-1) + 02^(3-1) + 12^(2-1) + 12^(1-1) = 12^3 + 0 + 12^1 + 1*2^0=8 + 2 + 1 = 11
2、八进制转十进制
规则:从 最低位 开始( 右边的 ),将每个位上的数提取出来,乘以 8 的( 位数-1 )次方然后求和
// 0123 转 10进制
38(1-1) + 28^1 + 1*8^2=3 + 16 + 64 = 83
3、十六进制转十进制
规则:从 最低位 开始( 右边的 ),将每个位上的数提取出来,乘以 16 的( 位数-1 )次方然后求和
// 0x34A 转 10进制
101 + 416 + 3*16^2 = 10 + 64 + 768 = 842
Practice:
格式化输出: %b 二进制 // %o 八进制 // %c 相应的 unicode 码点表示的字符
%x 十六进制表示,字母形式是小写a-f %X 十六进制表示,字母形式是大写 A-F
%p 十六进制表示,前缀 0x 代表地址
%d 代表使用标准的十进制进行格式化
// 将二进制 110001100 转成十进制
// 八进制 02456 转成十进制
// 十六进制 0xA45 转成十进制
110001100 = 0*2^0 + 0*2 + 1*2^2 + 1*2^3 + 0 + 0 + 0 + 1*2^7 +1*2^8
=4 + 8 + 128 + 256 = 396
02456 = 6*1 + 5*8 + 4*64 + 2*64*8 = 6+40+256+1024=1326
0xA45 = 5*1 + 4*16 + 10*16*16 = 5 + 64 + 2560 = 2629
var tt2 int = 110001100 // 这样不能表示二进制, 会以为是 10进制
var tt3 int = 02456
var tt4 int = 0xA45
//fmt.Println("tt2=",tt2)
fmt.Printf("%d,%d,%d",tt2,tt3,tt4)
// 110001100,1326,2629
ques: 怎么用变量保存 二进制的数字 ? 默认是 10 进制表示的
[ 十进制 => 其他进制 ]
十进制转换成 二进制
规则:将该数 不断除以2, 知道商为 0 为止,然后将每步得到的余数 倒过来
就是对应的二进制
// demo1: 将 56 转成二进制
56 /2 = 28(0) /2 = 14(0) /2 = 7(0) /2 = 3(1) /2 = 1(1) /2 =0(1)
// 111000
var tt5 int = 56
fmt.Printf("%b",tt5)
// 111000
十进制转换成 八进制
规则:将该数 不断除以8, 知道商为 0 为止,然后将每步得到的余数 倒过来
就是对应的八进制
//demo2: 将 156 转成 八进制
156/8 = 19(4) /8 = 2(3) /8 = 0(2)
// 234
var tt6 int = 156
fmt.Printf("%o",tt6)
// 234
十进制转换成 十六进制
规则:将该数 不断除以16, 知道商为 0 为止,然后将每步得到的余数 倒过来
就是对应的十六进制
//demo3: 将 356 转成 十六进制
356 /16 = 22(4) / 16 = 1(6) / 16 = 0(1)
// 164
var tt7 int = 356
fmt.Printf("%x\n",tt7)
// 164
// Practice
// 123 转成 二进制
// 678 转成 八进制
// 8912 转成 十六进制
123 /2 =61(1) / 2 = 30(1) /2 =15(0) /2 =7(1) /2 =3(1) /2=1(1) /2 =0(1)
// 1111011
678 /8 = 84(6) / 10(4) /8 = 1(2) /8 = 0(1)
// 1246
8912 /16 = 557(0) /16= 34(13) /16 =2(2) /16 = 0(2)
10a 11b 12c 13d
22d0
二进制转换成 八进制、十进制
2 => 8
规则:将 2进制 每三位一组( 从低位开始组合 ), 转成对应的八进制数即可
案例:
二进制 11010101 转成八进制
分组 11 010 101 // 11是3 010是2 101转8进制是5 所以是 325
2 => 16
规则:
将 2进制的每四位一组 ( 从低位开始组合 ),转成对应的十六进制数即可
案例:
二进制 11010101 转成 16进制
分组 1101 0101 // 1101 对应13是d 0101是5 所以是 0xd5
八进制/十六进制 => 二进制
相当于反过来:
规则: 将八进制的 每一位,转成对应的 一个 3 位的二进制数即可
案例:
将 0237 转成2进制
0 2 3 7 // 000 010 011 111
所以是 10011111
16机制 => 2进制
规则: 将16进制的 每一位,转成对应的 一个 4 位的二进制数即可
0x237
// 0010 0011 0111
[ 原码/反码/补码 ]
位运算:
二进制是 缝2进1的进位制, 0 和 1是基本算符
二进制 binary
在计算机的内部,运行各种运算时,最终都是以 二进制的方式进行
二进制有三个重要概念: 原码 、 反码、 补码
有符号而言:
二进制的最高位是符号位:0 表示正数, 1 表示负数
1 ===> 表示为 0000 0001
-1 ===> 1000 0001 8位bit是一个byte字节
- 正数的原码、反码、补码都一样
- 负数的反码 = 它的原码符号位不变, 其他位取反(0->1 1->0)
- 负数的补码 = 它的反码 + 1
- 0 的反码、补码都是 0
计算机运算时,都是以 补码的方式来运算
~~
比如
1的原码 0000 0001
反码 0000 0001
补码 0000 0001
-1的原码 1000 0001
反码 1111 1110
补码 1111 1111
位运算 和 移位运算