JavaScript中的进制转换

171 阅读2分钟

在JavaScript中自带两个方法实现进制之间的转换,parseInt(其它进制转换成十进制)和Number.prototype.toString(十进制转换成其它进制)。

parseInt

parseInt(string, radix)

  • string: 要被解析的值。如果参数不是一个字符串,则将其转换为字符串(使用  ToString 抽象操作)。字符串开头的空白符将会被忽略。
  • radix: 可选。一个介于2和36之间的整数(数学系统的基础),表示上述字符串的基数。比如参数"10"表示使用我们通常使用的十进制数值系统。始终指定此参数可以消除阅读该代码时的困惑并且保证转换结果可预测。当未指定基数时,不同的实现会产生不同的结果,通常将值默认为10

以下代码简单实现:

function ParseInt(s){
    if(typeof s === 'number') s = s.toString()
    if(typeof s !== 'string') return NaN
    s = s.trim() // 移除两边的空格
    let radix
    if((s.indexOf('0x') === 0 || s.indexOf('0X') === 0) && arguments.length < 2){
        radix = 16
        s = s.slice(2)
    }
    if(!radix){
        radix = arguments.length < 2 ? 10 : (Number(arguments[1]) || 10)
    }
    if(radix < 2 || radix > 36) return NaN
    let strToNumber = {}
    // 大于10进制
    for(let i = 65 ; i < 91; i++){
        let k = String.fromCharCode(i);
        strToNumber[k] = (i - 55) 
        strToNumber[k.toLocaleLowerCase()] = (i - 55)
        strToNumber[k.toLocaleUpperCase()] = (i - 55)
    }
    let ss = ''
    for(let i = 0, len = s.length; i < len; i++){
        let _ = strToNumber[s[i]] || s[i]
        if(!isNaN(_)&&_ < radix){
            ss += s[i]
        }else{
            break // 跳出循环
        }
    }
    if(ss === '') return NaN
    let res = 0, len = ss.length - 1;
    for(let i = len; i >= 0; i--){
        res += (strToNumber[ss[i]] || ss[i]) * Math.pow(radix, len - i)
    }
    return res
}
// 以下结果均为15
console.log(ParseInt("F", '16'))
console.log(ParseInt("17", 8))
console.log(ParseInt("15", 10))
console.log(ParseInt(15.99, 10))
console.log(ParseInt("FXX123", 16))
console.log(ParseInt("1111", 2))
console.log(ParseInt("15*3", 10))
console.log(ParseInt("12", 13))

经典问题:[1,2,3].map(parseInt)

parseInt(1, 0) // 1
parseInt(2, 1) // NaN
parseInt(3, 2) // NaN

toString

numObj.toString([radix])

  • radix: 指定要用于数字到字符串的转换的基数(从2到36)。如果未指定 radix 参数,则默认值为 10。
  • 异常信息:如果 toString() 的 radix 参数不在 2 到 36 之间,将会抛出一个 RangeError

以下代码简单实现:

    if(radix < 2 || radix > 36){
        throw new RangeError('toString() radix argument must be between 2 and 36')
    }
    let numToString = {}
    // 大于10进制
    for (let i = 65; i < 91; i++) {
        let k = String.fromCharCode(i);
        numToString[i-55] = k
        numToString[i-55] = k.toLocaleUpperCase()
        numToString[i-55] = k.toLocaleLowerCase()
    } 
    let res = ''
    while(num >= radix){
        let mod = num % radix;
        res = (numToString[mod] || mod) + res;
        num = (num - mod)/radix;
    } 
    return num >= 1 ? (numToString[num] || num) + res : res

以上全部内容,如有疑问,欢迎指正。Good Luck!

14.webp