# 进制分类
- 通常用的最多的就是
10进制
。 - 听的最多的就是
二进制
,因为计算机运行就是 0 和 1,逢 2 进 1。 - 前端看的最多的就是
16进制
,十六进制颜色码就是在软件中设定颜色值的代码。
当然还有各种8进制
之类的,就不多介绍,总之各有各的用途
# 进制之间的相互转换
# 10 进制 转 2 进制
正整数的计算
先从最简单的 10 进制转二进制开始,了解一下转换规则:除二取余,然后倒序排列,高位补零。
21 的二进制计算:
21 /2 parseInt => 10 ------------------------------- 余 1 ↑
10/2 parseInt => 5 ------------------------------- 余 0 |
5/2 parseInt => 2 ------------------------------- 余 1 |
2/2 parseInt => 2 ------------------------------- 余 0 |
1/2 parseInt => 0 ------------------------------- 余 1 结果
2
3
4
5
6
记住,倒着排序 10101
,验证下转成十进制: 1×2 的 4 次方+1×2 的 2 次方+1×2 的 0 次方=16+4+1=21。正确。
计算机一般是 8 位 16 位 32 位 64 位的,所以不够位高位补零。8 位表示法:00010101
遇到负数该如何计算?
先是将对应的正整数转换成二进制后,对二进制取反,然后对结果再加一
-21 的二进制计算:
1. 21 的二进制表示为: 00010101
2. 取反: 11101010 (这里的取反就是0换1,1换0)
3. 加一 : 11101011 (注意二进制的+1,一定是逢2进1。这里刚好最后一位数是0,所以不用进1)
4. 加上负数标识 `B` 得到 `00010101` (当然也有很多是直接在前面加负号而不是加B)
2
3
4
5
小数的计算方式
对小数点以后的数乘以 2,有一个结果吧,取结果的整数部分(不是 1 就是 0 喽),然后再用小数部分再乘以 2,再取结果的整数部分……以此类推,直到小数部分为 0 或者位数已经够了就 OK 了。
0.125 的二进制计算:
0.125 * 2 = 0.25 小数部分 0.25 parseInt 得 0 结果
0.25 * 2 = 0.5 小数部分 0.5 parseInt 得 0 |
0.5 * 2 = 1 小数部分 0 parseInt 得 1 ↓
2
3
4
小数的结果为顺着排序,所以结果为001
。所以 0.125 的二进制表示就是 0.001
当负数遇上小数
这部分查了很久的资料,很多网站也不提供负小数的运算演示,最后在 how to convert negative fraction decimal to binary (opens new window) 第二个回答中看到貌似正确的结果
大概的意思就是先按整数计算得出整数和小数分别的二进制,然后各自取反,在小数的二进制+1 (原话:To convert negative, procedure is standard, invert all bits and add 1 to the least significand digit.) 将1加到最低有效位
。注意这里是二进制+1,逢 2 进 1。所以1010.0011 + 0.0001=1010.0100
所以给出的例子就是:-5.75
得到的就是 1010.0100 (B1010.0100 或 -1010.0100)
https://tool.lu/hexconvert/
浮点数计算(未完成,末位加法)
// function getBinary(number, binary = '', count = 0) {
// if (number === 0 || count > 64) {
// return binary
// } else {
// let next = parseInt(number / 2)
// let remainder = (number % 2).toString()
// console.log(next, remainder)
// binary = remainder + binary
// count++
// return getBinary(next, binary, count)
// }
// }
function Decimal2Binary(num) {
if (isNaN(Number(num))) {
return 0
}
if (num === 0) {
return binary
}
let isNegative = num < 0
num = Math.abs(num)
let [integer, decimal] = num.toString().split('.')
let resInteger = radixConvert(integer, 2)
let resDecimal = decimal ? radixConvert(num - integer, 2) : ''
let result = `${resInteger}${resDecimal ? `.${resDecimal}` : ''}`
console.log(result)
if (isNegative) {
return reversal(result)
}
return result
}
function reversal(number, radix) {
if (!number) return ''
number = number.toString()
number = number
.replace(/1/g, 'one')
.replace(/0/g, 1)
.replace(/one/g, 0)
console.log(number)
return `B${addAtTheEnd(number, radix)}`
}
function addAtTheEnd(number, radix, add = 0) {
let numArr = number
.split('')
.reverse()
.map(item => {
if (item !== '.') {
return parseInt(item)
} else {
return '.'
}
})
numArr[0] = numArr[0] + add
numArr.some((item, index) => {
if (item >= radix) {
if (numArr[index + 1] === '.') {
numArr[index + 2] = parseInt(item / radix) + parseInt(numArr[index + 2] || '0')
} else {
numArr[index + 1] = parseInt(item / radix) + parseInt(numArr[index + 1] || '0')
}
numArr[index] = item % radix
return false
} else {
return true
}
})
return numArr.reverse().join('')
}
function radixConvert(number, radix, binary = '') {
if (number === 0 || binary.length >= 64) {
return binary
}
let next = 0
let remainder = 0
if (number >= 1) {
next = parseInt(number / radix)
remainder = (number % radix).toString()
binary = remainder + binary
if (binary.length >= 64) {
binary = binary.substr(-1, 64)
}
} else {
let tempNext = number * radix
remainder = parseInt(tempNext)
next = tempNext - remainder
binary = binary + remainder.toString()
if (binary.length >= 64) {
binary = binary.substr(0, 64)
}
}
return radixConvert(next, radix, binary)
}
console.log(Decimal2Binary(-2.5))
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