所谓进制,就是逢几进一,r 进制就是逢 r 进一,就是一种计数方法。
例如
* 一分钟六十秒,逢六十进一,就是六十进制;
* 一天二十四小时,逢二十四进一,就是二十四进制;
* 一星期七天,逢七进一,就是七进制;
* 一年十二个月,逢十二进一,就是十二进制;
* 小学数学是逢十进一,就是十进制;
* 而计算机中的数据只有 0 和 1,逢二进一,就是二进制。
注意
* 计算机只能识别二进制,人类最习惯使用的是十进制。
* 八进制数前面要加0(注意是数字零而不是字母 o),十六进制数前面要加0x或0X,而十进制前面什么都不加。
定义
十进制:
十进制为逢十进一,它只有 0、1、2、3、4、5、6、7、8、9 这十个基数。
逢十进一的意思就是:
9 再加 1 就变为 10,即向前进了一位,原来的 9 变成 0;
二进制:
二进制为逢二进一,它只有 0 和 1 两个基数。
逢二进一的意思就是:
* 1 再加 1 就变成 10,即向前进了一位,原来的 1 变成 0;
* 再加 1 就是 11;
* 再加 1 又逢二,再往前进一位,进一位后第二个 1 又逢二再进位,就是 100 了;
* 再加 1 变成 101,再加 1 变成 110,再加 1 变成 111,再加 1 变成 1000……
八进制:
八进制就是逢八进一,它只有 0、1、2、3、4、5、6、7 这八个基数。
逢八进一的意思就是:
* 7 再加 1 就变成 10,即向前进了一位,原来的 7 变成 0;
* 11 再加 7 就变成了 20,即向前进了一位,原来的 1(11中的个位数) 变成 0;
十六进制:
十六进制就是逢十六进一,它有 0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F 这十六个基数。注意:字母不区分大小写
逢十六进一的意思就是:
* f 再加 1 就变成 10,即向前进了一位,原来的 f 变成 0;
* 11 再加 f 就变成了 20,即向前进了一位,原来的 1(11中的个位数) 变成 0;
总结:
r 进制有 r 个基数,而且基数里面最大的是 r - 1,因为基数都是从 0 开始。
不同位数的值达到r时,就向前进1,原位数清0。
二进制: 十进制: 八进制: 十六进制:
0 1 =》1 0 1 = 1 0 1 = 1 0 1 = 1
1 1 =》 10 1 1 = 2 1 1 = 2 1 1 = 2
10 1 =》 11 2 1 = 3 2 1 = 3 2 1 = 3
11 1 =》 100 3 1 = 4 3 1 = 4 3 1 = 4
100 1 =》 101 4 1 = 5 4 1 = 5 4 1 = 5
101 1 =》 110 5 1 = 6 5 1 = 6 5 1 = 6
110 1 =》 111 6 1 = 7 6 1 = 7 6 1 = 7
111 1 =》 1000 7 1 = 8 7 1 = 10 7 1 = 8
1000 1 =》 1001 8 1 = 9 10 1 = 11 8 1 = 9
1001 1 =》 1010 9 1 = 10 11 1 = 12 9 1 = a
1010 1 =》 1011 10 1 = 11 12 1 = 13 a 1 = b
1011 1 =》 1100 11 1 = 12 13 1 = 14 b 1 = c
1100 1 =》 1101 12 1 = 13 14 1 = 15 c 1 = d
1101 1 =》 1110 13 1 = 14 15 1 = 16 d 1 = e
1110 1 =》 1111 14 1 = 15 16 1 = 17 e 1 = f
1111 1 =》 10000 15 1 = 16 17 1 = 20 f 1 = 10
M进制转换N进制的函数
r进制转换十进制:parseInt(str,radix)
string :如果string不是字符串,它底层将通过使用 ToString 抽象操作 将其转成字符串
radix:范围在 [2,36]之间,表示当前 string 表示为几进制,在 radix 为 undefined,或者基数为 0 或者没有指定的情况下,JavaScript 作如下处理:
* 如果字符串 string 以"0x"或者"0X"开头, 则基数是16 (16进制)
* 如果字符串 string 以其它任何值开头,则基数是10 (十进制)
* 其他永远都要明确给出radix参数的值
* 结果返回值为number类型
注意:如果第一个参数的第一个字符 跟 第二个参数的进制类型不相符,parseInt返回NaN。可以调用isNaN 来判断 parseInt 是否返回 NaN
eg: parseInt('321',2) // NaN '321' 第一个字符非 0,1 这两个基数
eg: parseInt('321',37) // NaN radix 超过了区间[2,36]
eg: isNaN(parseInt(0101,2)) // true (0101).toString() => 65
十进制转换r进制:(Number).toString(radix)
Number:为一个十进制的数值,当然你也可以写一个16进制的数值,注意如果直接
radix:范围在 [2,36]之间,表示将 Number 转换成几进制,如果未指定 radix 参数,则默认值为 10;
如果 toString() 的 radix 参数不在 2 到 36 之间,将会抛出一个 RangeError。
为什么 2.toString(radix) 会报错呢?
* 那是因为第一个点会被解析成小数点的点,如:2.0,后面的0省略了就是2.,因为2..toString(radix)才能正常执行。
* 所以正常写法都是(2).toString(radix)
最终JavaScript函数:
function radixTransform(num,from,to){
num = typeof(num) === 'string' ? num : String(num)
if ((from > 36 && from < 2) || (to > 36 && to < 2)) throw new Error('进制参数取值区间在[2,36]')
let result = parseInt(num,from)
if (typeof(result) === 'number' && isNaN(result)) throw new Error('转换值错误')
return result.toString(to)
}
进制之间的对应关系
二进制 | 八进制 | 十进制 | 十六进制 |
0 | 0 | 0 | 0 |
1 | 1 | 1 | 1 |
10 | 2 | 2 | 2 |
11 | 3 | 3 | 3 |
100 | 4 | 4 | 4 |
101 | 5 | 5 | 5 |
110 | 6 | 6 | 6 |
111 | 7 | 7 | 7 |
1000 | 10 | 8 | 8 |
1001 | 11 | 9 | 9 |
1010 | 12 | 10 | a |
1011 | 13 | 11 | b |
1100 | 14 | 12 | c |
1101 | 15 | 13 | d |
1110 | 16 | 14 | e |
1111 | 17 | 15 | f |
原因很简单,就是因为我们都有十个手指!进制的起源是用于记数的,人类刚开始都是用手指计数的。
即使是现在的小朋友算数也还是喜欢用手指,所以人类最习惯用十进制。
计算机为什么用的是二进制
因为二进制从硬件上比较容易实现。
任何事物最少也有两种不同的状态,所以区分成两种状态比较容易。
但是要将一个硬件硬生生地区分成十种不同的状态,这个就太难、太复杂了。