实现二进制与十进制的互相转化的两个函数
Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 684
Author 回答者: shfshanyue
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));
Author 回答者: heretic-G
// 二进制转十进制
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;
}
Author 回答者: justorez
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);