Answers:
function dec2bin(dec){
return (dec >>> 0).toString(2);
}
dec2bin(1); // 1
dec2bin(-1); // 11111111111111111111111111111111
dec2bin(256); // 100000000
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 /programming/10936600/javascript-decimal-to-binary-64-bit
*/
return (~dec).toString(2);
}
}
我从这里得到了一些帮助
-3
return 1
),更新似乎仍然不起作用。我也相信dec > 0
应该是dec >= 0
,至少应该固定为0。因为dec2Bin(0)
return 10
。
“转换为二进制”中的二进制可以涉及三个主要方面。位置编号系统,内存中的二进制表示形式或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"
一个简单的方法就是...
Number(42).toString(2);
// "101010"
(42).toString(2)
42..toString(2)
1.
与之相同1.0
或相同的内容1
(类似地,您也可以省略之前的部分并.5
代替编写0.5
)。因此,在该示例中,第一个点是小数点分隔符,它是数字的一部分,第二个点是用于在该数字上调用方法的点运算符。您必须使用两个点(或将数字括在括号中),并且不能只写,42.toString(2)
因为解析器将点视为小数点分隔符,并且由于缺少点运算符而引发错误。
此答案尝试使用绝对值在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:
作为额外的奖励,你可以支持任意基数(2-36),如果您在⌈64执行二进制补码转换为负数/日志2使用(基数)⌉位数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}
如果您对我以前使用ArrayBuffer
来在a Float64Array
和a 之间创建并集的答案感兴趣Uint16Array
,请参考该答案的修订历史记录。
-(2**53)-1
对2**53-1
,而不是只-(2**31)
对2**31-1
像安南的答案。
我认为适合32位的解决方案是此答案结尾的代码,该代码来自developer.mozilla.org(MDN),但添加了几行用于A)格式设置和B)检查数字在范围内。
有些人建议x.toString(2)
对负数无效,它只是在负数上加减号,这是不好的。
费尔南多(Fernando)提到了一个简单的解决方案,(x>>>0).toString(2);
该方法适用于负数,但是当x为正数时会有一个小问题。它的输出以1开头,对于正数来说,这是不正确的2s补码。
任何不了解正数从0开始和负数从1开始(在2s补码中)的事实的人都可以在2s补码上检查此SO QnA。什么是“ 2的补码”?
一种解决方案可能是在正数前加上0,这是我在此答案的较早版本中所做的。一个人有时可以接受一个33位的数字,或者可以确保要转换的数字在-(2 ^ 31)<= x <2 ^ 31-1范围内。因此,该数字始终为32位。但是,您可以在mozilla.org上使用此解决方案,而不是这样做
帕特里克(Patrick)的答案和代码很长,而且显然适用于64位,但是有一个评论者发现的错误,并且评论者修复了帕特里克(bug)的错误,但是帕特里克在他的代码中有一些“不可思议的数字”,他没有对此发表评论并且拥有被遗忘的帕特里克不再完全了解自己的代码/代码为什么有效。
安南的术语有误和不清楚,但提到了developer.mozilla.org https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators的解决方案。 此方法适用于32位数字。
该代码非常紧凑,具有三行功能。
但是我添加了一个正则表达式以将输出格式化为8位组。基于如何在JavaScript中以逗号将数字打印为数千个分隔符 (我刚刚对其进行了修改,从右到左3s分组并添加逗号,从右到左8s分组并添加空格)
并且,虽然mozilla对nMask(输入的数字)的大小发表了评论。它必须在范围内,但当数字超出范围时,他们没有进行测试或抛出错误,所以我已经补充说。
我不确定为什么他们将其参数命名为“ nMask”,但我将保持不变。
参考:https : //developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
function createBinaryString(nMask) {
// nMask must be between -2147483648 and 2147483647
if (nMask > 2**31-1)
throw "number too large. number shouldn't be > 2**31-1"; //added
if (nMask < -1*(2**31))
throw "number too far negative, number shouldn't be < 2**31" //added
for (var nFlag = 0, nShifted = nMask, sMask = ''; nFlag < 32;
nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1);
sMask=sMask.replace(/\B(?=(.{8})+(?!.))/g, " ") // added
return sMask;
}
console.log(createBinaryString(-1)) // "11111111 11111111 11111111 11111111"
console.log(createBinaryString(1024)) // "00000000 00000000 00000100 00000000"
console.log(createBinaryString(-2)) // "11111111 11111111 11111111 11111110"
console.log(createBinaryString(-1024)) // "11111111 11111111 11111100 00000000"
您可以编写自己的返回位数组的函数。示例如何将数字转换为位
上一行的示例:2 * 4 = 8,余数为1,所以9 = 1 0 0 1
function numToBit(num){
var number = num
var result = []
while(number >= 1 ){
result.unshift(Math.floor(number%2))
number = number/2
}
return result
}
从下至上读取余数。从中间到顶部的数字1。
Math.floor(number%2)
代替number = Math.floor(number/2)
?
我使用了不同的方法来完成此任务。我决定不在我的项目中使用此代码,但我认为我会将其保留在适当的位置,以防对某人有用。
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("---");
另一种选择
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));
这是我的代码:
var x = prompt("enter number", "7");
var i = 0;
var binaryvar = " ";
function add(n) {
if (n == 0) {
binaryvar = "0" + binaryvar;
}
else {
binaryvar = "1" + binaryvar;
}
}
function binary() {
while (i < 1) {
if (x == 1) {
add(1);
document.write(binaryvar);
break;
}
else {
if (x % 2 == 0) {
x = x / 2;
add(0);
}
else {
x = (x - 1) / 2;
add(1);
}
}
}
}
binary();
这是解决方案。其实很简单
function binaries(num1){
var str = num1.toString(2)
return(console.log('The binary form of ' + num1 + ' is: ' + str))
}
binaries(3
)
/*
According to MDN, Number.prototype.toString() overrides
Object.prototype.toString() with the useful distinction that you can
pass in a single integer argument. This argument is an optional radix,
numbers 2 to 36 allowed.So in the example above, we’re passing in 2 to
get a string representation of the binary for the base 10 number 100,
i.e. 1100100.
*/