将n进制转换成10进制数
function transformToTen(num, fromRadix) {
if (typeof num !== 'string') throw new Error()
if (!num || !fromRadix || fromRadix === 10) return num
if (fromRadix < 2 || fromRadix > 36) { throw new TypeError('The fromRadix range is limited to 2-36.') }
num = num.trim()
let isPositive = true
if (/^[+-]/.test(num)) {
isPositive = /^[+]/.test(num)
num = num.slice(1)
}
if (fromRadix === 16 && /^0x/.test(num)) {
num = num.slice(2)
}
num = num.replace(/^0/, '')
function exchange(letter) {
const code = letter.charCodeAt(0)
if (letter >= 'A' && letter <= 'Z') {
return code - 'A'.charCodeAt(0) + 10
} else if (letter >= 'a' && letter <= 'z') {
return code - 'a'.charCodeAt(0) + 10
} else {
return code - '0'.charCodeAt(0)
}
}
let total = 0
const str = num.toString()
const integer = str.split('.')[0] ? str.split('.')[0].split('') : []
const decimal = str.split('.')[1] ? str.split('.')[1].replace(/0+$/, '').split('') : []
for (const [index, letter] of integer.entries()) {
const num = fromRadix > 10 ? exchange(letter) : +letter
total += num * Math.pow(fromRadix, integer.length - index - 1)
}
for (const [index, letter] of decimal.entries()) {
const num = fromRadix > 10 ? exchange(letter) : +letter
if (isPositive) {
total += num * Math.pow(fromRadix, -(index+1))
} else {
total -= num * Math.pow(fromRadix, -(index+1))
}
}
return isPositive ? total : -total
}
将10进制转换成n进制数
function transformFromTen(num, toRadix, decimalCounts = 0) {
if (typeof num !== 'number') throw new TypeError()
if (!num || !toRadix || toRadix === 10) return num
if (toRadix < 2 || toRadix > 36) { throw new Error() }
const fill = (str) => toRadix === 16 ? `0x${str}` : toRadix === 8 ? `0${str}` : str
const getLetter = (num) => num >= 10 ? String.fromCharCode('a'.charCodeAt(0) + num - 10) : `${num}`
const isPositive = num > 0
num = Math.abs(num)
let integer = Math.floor(num)
let decimal = num - integer
let str = ''
while (integer >= toRadix) {
const yu = integer % toRadix
str = `${getLetter(yu)}${str}`
integer = Math.floor(integer / toRadix)
}
str = `${getLetter(integer)}${str}`
if (!decimal || !decimalCounts) return fill(str)
if (decimalCounts) str += '.'
for (let i = 1; i <= decimalCounts; i++) {
const num = Math.floor(toRadix * decimal)
str = `${str}${getLetter(num)}`
decimal = toRadix * decimal - num
}
return isPositive ? fill(str) : `-${fill(str)}`
}
n进制之间相互转换
function transform(num, fromRadix, toRadix, decimalCounts) {
const ten = transformToTen(num, fromRadix)
return transformFromTen(ten, toRadix, decimalCounts)
}
参考 / 引用 / 测试