shfshanyue / Daily-Question

互联网大厂内推及大厂面经整理,并且每天一道面试题推送。每天五分钟,半年大厂中
https://q.shanyue.tech
4.92k stars 508 forks source link

【Q666】实现二进制与十进制的互相转化的两个函数 #684

Open shfshanyue opened 3 years ago

shfshanyue commented 3 years ago

代码见:实现二进制与十进制的互相转化的两个函数

function integerToBin (num) {
  // 64
  const result = []
  while (num / 2) {
    next = num % 2
    num = Math.floor(num / 2)
    result.unshift(next)
  }
  return result
}

function fractionalToBin (num) {
  const result = []
  let i = 0
  while (num !== 0 && i < 54) {
    num = num * 2

    next = num >= 1 ? 1 : 0
    num = num % 1
    i++
    result.push(next)
  }
  return result
}

function decToBinary (num) {
  // 1.5
  const [int, fraction] = String(num).split(/(?=\.)/).map((x, i) => {
    return i === 0 ? integerToBin(x) : fractionalToBin(x)
  })
  return [int, fraction]
}

function binToDec (num) {
  const [_int, _fraction] = String(num).split('.')
  const int = _int.split('').reduceRight((acc, x, i) => {
    return acc + x * 2 ** i
  }, 0)
  const fraction = _fraction ? _fraction.split('').reduce((acc, x, i) => {
    return acc + x * 2 ** -(i + 1)
  }, 0) : 0
  return `${int}${fraction ? '.' + fraction.toString().slice(2) : ''}`
}

console.log(16, integerToBin(16), Number(16).toString(2))
console.log(18, integerToBin(18), Number(18).toString(2))
console.log(0.5, fractionalToBin(0.5), Number(0.5).toString(2))
console.log(0.1, fractionalToBin(0.1), Number(0.1).toString(2))
console.log(1.1, decToBinary(1.1), Number(1.1).toString(2))

console.log(7.875, decToBinary(7.875), Number(7.875).toString(2))
console.log('111.111', binToDec('111.111'), parseInt('111.111', 2))
heretic-G commented 3 years ago
// 二进制转十进制

function binaryToDecimal (num) {
    let negative = false
    if (num < 0) {
        num = -num
        negative = true
    }
    num += ''
    let point = num.indexOf('.')
    let int
    let intDecimal = 0
    let float
    let floatDecimal = 0

    if (point > -1) {
        int = num.slice(0, point)
        float = `${num.slice(point + 1)}`
    } else {
        int = num
    }
    if(int) {
        for (let i = 0; i < int.length; i++) {
            intDecimal += int[int.length - i - 1] * Math.pow(2, i)
        }
    }

    if (float) {
        for (let i = 0; i < float.length; i++) {
            floatDecimal += float[i] * Math.pow(2, -(i + 1))
        }
    }
    let result = ''
    if (negative) {
        result += '-'
    }
    result += (intDecimal + floatDecimal)
    return +result
}
// 十进制转二进制

function decimalToBinary (num) {
    let negative = false
    if (num < 0) {
        num = -num
        negative = true
    }
    num += ''
    let point = num.indexOf('.')
    let int
    let intBinary = ''
    let float
    let floatBinary = ''

    if (point > -1) {
        int = num.slice(0, point)
        float = Number(`0${num.slice(point)}`)
    } else {
        int = num
    }
    if(int) {
        int = +int
        while (int >= 1) {
            intBinary = int % 2 + intBinary
            int = int / 2 | 0
        }
    }

    if (float) {
        while(float) {
            float *= 2
            if (float >= 1) {
                floatBinary += 1
            } else {
                floatBinary += 0
            }
            float = float % 1
        }
    }
    let result = ''
    if (negative) {
        result += '-'
    }
    result += (`${intBinary || 0}.${floatBinary}`)
    return result
}
justorez commented 1 year ago
function binToDec (num) {
  const [_int, _fraction] = String(num).split('.')
-  const int = _int.split('').reduceRight((acc, x, i) => {
    return acc + x * 2 ** i
  }, 0)
  const fraction = _fraction ? _fraction.split('').reduce((acc, x, i) => {
    return acc + x * 2 ** -(i + 1)
  }, 0) : 0
  return `${int}${fraction ? '.' + fraction.toString().slice(2) : ''}`
}

@shfshanyue 这一行有错误,reducRight 里的 i 是数组元素的当前索引,不是从 0 开始的。例如 13 是 1101,上面方法会计算成 11。

// 修正
const int = _int.split('').reduce((acc, x, i, arr) => {
    return acc + Number(x) * 2 ** (arr.length - 1 - i)
}, 0)
kurodasense commented 4 months ago

也可以用toString()来转成二进制,然后用parseInt()来转回十进制:

function BinToInteger(bin) { return parseInt(bin, 2); } const bin = IntegerToBin(1023012); const int = BinToInteger(bin); console.log(bin); // 11111001110000100100 console.log(int); // 1023012