JavaScript中的进制和转换
在目前的计算机系统中,所有信息都是以0或1的形式(即二进制形式)来保存的。而我们生活中常常使用的是十进制,在js中,我们常常又会遇到十六进制形式,比如:rgb颜色值的表示等。所以,弄清楚他们之间的关联和区别是非常必要的。
本篇聊聊JavaScript中的进制。
二进制
英文 binary
表示二进制的,二进制以0b
或0B
开头,来看一个例子:
let num1 = 0b1001
let num2 = 0B1001
console.log(num1) // 9
console.log(num2) // 9
当使用console.log打印时,会将值转换为十进制显示到控制台上。对于num1,它的十进制值为 1 * 2 ** 3 + 0 * 2**2 + 0 * 2 ** 1 + 1 * 2 ** 0
,结果为9。
八进制
英文 octal
表示八进制的,八进制以0(零)开头,八进制的数字序列为(0~7),如果字面值中的数值超出了范围,那么前导零将被忽略,后面的数值将被当作十进制数值解析。另外,八进制字面量在严格模式下是无效的,会导致支持的 JavaScript 引擎抛出错误。
来看一个例子:
var num1 = 0123
console.log(num1) // 83
var num2 = 089
console.log(num2) // 89, 超出范围,会被忽略
对于num1,它的八进制表示为123,十进制的值为 1 * 8 ** 2 + 2 * 8 ** 1 + 3 * 8 ** 0
,结果为83。
十进制
十进制是我们生活中常用的进制,在js中:
var num1 = 12
其值就是12。
十六进制
英文 hexadecimal
表示十六进制的,十六进制以0x
或0X
开头,来看一个例子:
var num1 = 0x1e2
console.log(num1) // 482
var num2 = 0X1E2
console.log(num2) // 482
对于num1,它的十六进制表示为1e2,十进制的值为 1 * 16 ** 2 + 14 * 16 ** 1 + 2 * 16 ** 0
,结果为482。
进制转换
在实际的开发过程中,我们常常需要对不同的进制进行转换,怎么做呢?在js中,本身提供了相关的转换函数toString()
,但是用起来不太方便,在这里,我写了一个十进制转十六进制的工具函数:
/**
* get hexadecimal string from a decimal integer
* @param {number} int
* @returns {string | Error}
*/
function decimalToHex(int) {
if (typeof int === 'number' && Number.isInteger(int)) {
return Number(int).toString(16)
} else {
return new Error('must be integer')
}
}
上面工具函数能够将十进制转换为十六进制字符串的格式。
反过来,如果要将十六进制字符串转换为十进制,怎么做呢?这要借助于parseInt()
函数,我也写了一个工具函数:
/**
* get decimal integer from a hexadecimal string
* @param {string} hexStr
* @returns {number | Error}
*/
function hexToDecimal(hexStr) {
const hexs = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
const lowerStrs = hexStr.toLowerCase()
let valid = true
for (let s of lowerStrs) {
if (hexs.includes(s) === false) {
valid = false
}
}
if (typeof hexStr === 'string' && valid) {
return parseInt(hexStr, 16)
} else {
return new Error('invalid hexadecimal string')
}
}
需要注意的是,需要先对转换的值进行合法性判断,合法,才对其进行转换,不合法,则返回一个错误对象。