我希望看到二进制形式的正整数或负整数。
很像这个问题,但是是针对JavaScript的。
我希望看到二进制形式的正整数或负整数。
很像这个问题,但是是针对JavaScript的。
当前回答
还有一个选择
const decToBin = dec => {
let bin = '';
let f = false;
while (!f) {
bin = bin + (dec % 2);
dec = Math.trunc(dec / 2);
if (dec === 0 ) f = true;
}
return bin.split("").reverse().join("");
}
console.log(decToBin(0));
console.log(decToBin(1));
console.log(decToBin(2));
console.log(decToBin(3));
console.log(decToBin(4));
console.log(decToBin(5));
console.log(decToBin(6));
其他回答
一个简单的方法就是……
Number(42).toString(2);
// "101010"
逻辑可以被任何编程语言实现的实际解决方案:
如果你确定它只是积极的:
var a = 0;
var n = 12; // your input
var m = 1;
while(n) {
a = a + n%2*m;
n = Math.floor(n/2);
m = m*10;
}
console.log(n, ':', a) // 12 : 1100
若能负或正——
(n >>> 0).toString(2)
这个答案试图用214748364810(231)- 900719925474099110(253-1)范围内的绝对值来处理输入。
在JavaScript中,数字以64位浮点表示形式存储,但位操作将它们强制转换为二进制补码格式的32位整数,因此任何使用位操作的方法都将输出范围限制为-214748364810(-231)- 214748364710(231-1)。
然而,如果避免按位操作,并且只使用数学运算来保留64位浮点表示法,则可以通过符号扩展53位的twosComplement,将任何安全整数可靠地转换为64位的二进制补码表示法:
function toBinary (value) { if (!Number.isSafeInteger(value)) { throw new TypeError('value must be a safe integer'); } const negative = value < 0; const twosComplement = negative ? Number.MAX_SAFE_INTEGER + value + 1 : value; const signExtend = negative ? '1' : '0'; return twosComplement.toString(2).padStart(53, '0').padStart(64, signExtend); } function format (value) { console.log(value.toString().padStart(64)); console.log(value.toString(2).padStart(64)); console.log(toBinary(value)); } format(8); format(-8); format(2**33-1); format(-(2**33-1)); format(2**53-1); format(-(2**53-1)); format(2**52); format(-(2**52)); format(2**52+1); format(-(2**52+1)); .as-console-wrapper{max-height:100%!important}
对于较旧的浏览器,存在以下函数和值的填充:
Number.isSafeInteger () Number.isInteger () 号码。MAX_SAFE_INTEGER String.prototype.padStart ()
作为额外的奖励,如果您使用BigInt对⌈64 / log2(基数)⌉数字中的负数执行两个补数转换,您可以支持任何基数(2-36):
function toRadix (value, radix) { if (!Number.isSafeInteger(value)) { throw new TypeError('value must be a safe integer'); } const digits = Math.ceil(64 / Math.log2(radix)); const twosComplement = value < 0 ? BigInt(radix) ** BigInt(digits) + BigInt(value) : value; return twosComplement.toString(radix).padStart(digits, '0'); } console.log(toRadix(0xcba9876543210, 2)); console.log(toRadix(-0xcba9876543210, 2)); console.log(toRadix(0xcba9876543210, 16)); console.log(toRadix(-0xcba9876543210, 16)); console.log(toRadix(0x1032547698bac, 2)); console.log(toRadix(-0x1032547698bac, 2)); console.log(toRadix(0x1032547698bac, 16)); console.log(toRadix(-0x1032547698bac, 16)); .as-console-wrapper{max-height:100%!important}
如果你对我的旧答案感兴趣,使用ArrayBuffer来创建一个Float64Array和Uint16Array之间的联盟,请参考这个答案的修订历史。
“convert to binary”中的二进制可以指三个主要的东西。位置数系统,内存中的二进制表示或32位位串。(64位位串参见Patrick Roberts的回答)
1. 数字系统
(123456). tostring(2)将数字转换为以2为基数的位置数字系统。在这个系统中,负数被写成负号,就像在十进制中一样。
2. 内部表示
数字的内部表示是64位浮点数,在这个答案中讨论了一些限制。没有简单的方法在javascript中创建一个比特字符串表示,也不能访问特定的位。
3.掩码和位操作符
MDN很好地概述了位操作符的工作方式。重要的是:
位操作符将其操作数视为32位序列(0和1)。
在应用操作之前,64位浮点数被转换为32位有符号整数。在它们被转换回来之后。
下面是将数字转换为32位字符串的MDN示例代码。
function createBinaryString (nMask) {
// nMask must be between -2147483648 and 2147483647
for (var nFlag = 0, nShifted = nMask, sMask = ""; nFlag < 32;
nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1);
return sMask;
}
createBinaryString(0) //-> "00000000000000000000000000000000"
createBinaryString(123) //-> "00000000000000000000000001111011"
createBinaryString(-1) //-> "11111111111111111111111111111111"
createBinaryString(-1123456) //-> "11111111111011101101101110000000"
createBinaryString(0x7fffffff) //-> "01111111111111111111111111111111"
我用了一种不同的方法来解决这个问题。我决定在我的项目中不使用这段代码,但我想我会把它放在相关的地方,以防它对某人有用。
Doesn't use bit-shifting or two's complement coercion. You choose the number of bits that comes out (it checks for valid values of '8', '16', '32', but I suppose you could change that) You choose whether to treat it as a signed or unsigned integer. It will check for range issues given the combination of signed/unsigned and number of bits, though you'll want to improve the error handling. It also has the "reverse" version of the function which converts the bits back to the int. You'll need that since there's probably nothing else that will interpret this output :D
function intToBitString(input, size, unsigned) { if ([8, 16, 32].indexOf(size) == -1) { throw "invalid params"; } var min = unsigned ? 0 : - (2 ** size / 2); var limit = unsigned ? 2 ** size : 2 ** size / 2; if (!Number.isInteger(input) || input < min || input >= limit) { throw "out of range or not an int"; } if (!unsigned) { input += limit; } var binary = input.toString(2).replace(/^-/, ''); return binary.padStart(size, '0'); } function bitStringToInt(input, size, unsigned) { if ([8, 16, 32].indexOf(size) == -1) { throw "invalid params"; } input = parseInt(input, 2); if (!unsigned) { input -= 2 ** size / 2; } return input; } // EXAMPLES var res; console.log("(uint8)10"); res = intToBitString(10, 8, true); console.log("intToBitString(res, 8, true)"); console.log(res); console.log("reverse:", bitStringToInt(res, 8, true)); console.log("---"); console.log("(uint8)127"); res = intToBitString(127, 8, true); console.log("intToBitString(res, 8, true)"); console.log(res); console.log("reverse:", bitStringToInt(res, 8, true)); console.log("---"); console.log("(int8)127"); res = intToBitString(127, 8, false); console.log("intToBitString(res, 8, false)"); console.log(res); console.log("reverse:", bitStringToInt(res, 8, false)); console.log("---"); console.log("(int8)-128"); res = intToBitString(-128, 8, false); console.log("intToBitString(res, 8, true)"); console.log(res); console.log("reverse:", bitStringToInt(res, 8, true)); console.log("---"); console.log("(uint16)5000"); res = intToBitString(5000, 16, true); console.log("intToBitString(res, 16, true)"); console.log(res); console.log("reverse:", bitStringToInt(res, 16, true)); console.log("---"); console.log("(uint32)5000"); res = intToBitString(5000, 32, true); console.log("intToBitString(res, 32, true)"); console.log(res); console.log("reverse:", bitStringToInt(res, 32, true)); console.log("---");