# 进制分类

  • 通常用的最多的就是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  结果
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)
1
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   ↓
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))
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
Last Updated: 5/9/2021, 10:45:03 PM