我想看到二进制的整数,正数或负数。
更喜欢这个问题,但对于 JavaScript。
我想看到二进制的整数,正数或负数。
更喜欢这个问题,但对于 JavaScript。
function dec2bin(dec) {
return (dec >>> 0).toString(2);
}
console.log(dec2bin(1)); // 1
console.log(dec2bin(-1)); // 11111111111111111111111111111111
console.log(dec2bin(256)); // 100000000
console.log(dec2bin(-256)); // 11111111111111111111111100000000
您可以使用Number.toString(2)
函数,但在表示负数时存在一些问题。例如,(-1).toString(2)
输出为"-1"
。
要解决此问题,您可以使用无符号右移按位运算符 ( >>>
) 将您的数字强制为无符号整数。
如果您运行,(-1 >>> 0).toString(2)
您会将数字 0 向右移动,这不会改变数字本身,但它将表示为一个无符号整数。上面的代码将"11111111111111111111111111111111"
正确输出。
这个问题有进一步的解释。
-3 >>> 0
(逻辑右移)将其参数强制为无符号整数,这就是为什么您会得到 -3 的 32 位二进制补码表示。
尝试
num.toString(2);
2 是基数,可以是 2 到 36 之间的任何基数
来源在这里
更新:
这仅适用于正数,Javascript 以二进制补码表示法表示负二进制整数。我制作了这个应该可以解决问题的小函数,但我没有正确测试它:
function dec2Bin(dec)
{
if(dec >= 0) {
return dec.toString(2);
}
else {
/* Here you could represent the number in 2s compliment but this is not what
JS uses as its not sure how many bits are in your number range. There are
some suggestions https://stackoverflow.com/questions/10936600/javascript-decimal-to-binary-64-bit
*/
return (~dec).toString(2);
}
}
我从这里得到了一些帮助
一个简单的方法就是...
Number(42).toString(2);
// "101010"
“转换为二进制”中的二进制可以指三个主要的东西。位置数字系统,内存中的二进制表示或 32 位位串。(对于 64 位位串,请参阅Patrick Roberts 的回答)
1. 数字系统
(123456).toString(2)
将数字转换为基数为 2 的位置数字系统。在这个系统中,负数像十进制一样用减号书写。
2. 内部代表
数字的内部表示是64 位浮点数,此答案中讨论了一些限制。有没有简单的方法来创建的javascript也不能访问特定位的该位串表示。
3. 掩码和位运算符
MDN很好地概述了按位运算符的工作原理。重要的:
按位运算符将其操作数视为32 位(零和一)的序列
在应用运算之前,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"
此答案尝试使用 2147483648 10 (2 31 ) – 9007199254740991 10 (2 53 -1)范围内的绝对值来解决输入。
在JavaScript中,号码被存储在64位浮点表示,但按位操作强迫他们到32位整数中2的补码格式,所以它使用按位操作的任何方法限制输出的范围,以-2147483648 10(-2 31) – 2147483647 10 (2 31 -1)。
但是,如果避免按位运算并且仅使用数学运算保留 64 位浮点表示,我们可以通过对 53 位进行符号扩展,将任何安全整数可靠地转换为 64 位二进制补码二进制表示法twosComplement
:
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}
对于较旧的浏览器,存在以下函数和值的 polyfill:
作为额外的好处,如果您使用 ⌈64 / log 2 (radix) ⌉ 数字对负数执行二进制补码转换,则可以支持任何基数 (2–36) BigInt
:
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}
如果您对我使用 anArrayBuffer
在 aFloat64Array
和 a之间创建联合的旧答案感兴趣Uint16Array
,请参阅此答案的修订历史记录。