ฉันต้องการดูจำนวนเต็มบวกหรือลบเป็นเลขฐานสอง
ค่อนข้างชอบคำถามนี้แต่สำหรับ JavaScript
ฉันต้องการดูจำนวนเต็มบวกหรือลบเป็นเลขฐานสอง
ค่อนข้างชอบคำถามนี้แต่สำหรับ JavaScript
คำตอบ:
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"
ในการแก้ไขปัญหานี้คุณสามารถใช้ตัวดำเนินการ bitwise กะด้านขวาที่ไม่ได้ลงชื่อ ( >>>
) เพื่อบีบอัดหมายเลขของคุณเป็นจำนวนเต็มที่ไม่ได้ลงชื่อ
หากคุณเรียกใช้(-1 >>> 0).toString(2)
คุณจะเลื่อนตัวเลข 0 บิตไปทางขวาซึ่งจะไม่เปลี่ยนตัวเลข แต่จะแสดงเป็นจำนวนเต็มที่ไม่ได้ลงนาม รหัสด้านบนจะส่งออก"11111111111111111111111111111111"
อย่างถูกต้อง
คำถามนี้มีคำอธิบายเพิ่มเติม
-3 >>> 0
(shift เชิงตรรกะด้านขวา) รวมอาร์กิวเมนต์ของมันกับจำนวนเต็มที่ไม่ได้ลงนามซึ่งเป็นเหตุผลว่าทำไมคุณถึงได้รับการแสดงส่วนประกอบ 32 บิตที่สองของ -3
ลอง
num.toString(2);
2 คือฐานและสามารถเป็นฐานใด ๆ ระหว่าง 2 และ 36
UPDATE:
สิ่งนี้จะใช้ได้กับตัวเลขที่เป็นบวกเท่านั้นจาวาสคริปต์แทนเลขจำนวนเต็มฐานสองเชิงลบในรูปแบบสองส่วน ฉันทำฟังก์ชั่นเล็ก ๆ น้อย ๆ ซึ่งควรทำเคล็ดลับฉันยังไม่ได้ทดสอบอย่างถูกต้อง:
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
ส่งคืน1
) นอกจากนี้ผมเชื่อว่าdec > 0
ควรจะเป็นdec >= 0
ซึ่งควรอย่างน้อยการแก้ไข 0. เพราะผลตอบแทนdec2Bin(0)
10
ไบนารีใน 'แปลงเป็นไบนารี' สามารถอ้างถึงสามสิ่งหลัก ระบบตัวเลขตำแหน่งการแทนค่าฐานสองในหน่วยความจำหรือบิต 32 บิต (สำหรับ bitstrings 64 บิตดูคำตอบของ Patrick Roberts )
1. ระบบตัวเลข
(123456).toString(2)
จะแปลงตัวเลขฐาน 2 ระบบเลขตำแหน่ง ในระบบนี้จำนวนลบจะเขียนด้วยเครื่องหมายลบเช่นเดียวกับในทศนิยม
2. การเป็นตัวแทนภายใน
การแสดงตัวเลขภายในเป็นทศนิยม64 บิตและกล่าวถึงข้อ จำกัด บางอย่างในคำตอบนี้ นอกจากนี้ไม่มีวิธีง่ายๆในการสร้างการแสดงบิตสตริงนี้ในจาวาสคริปต์มิได้เข้าถึงบิตที่เฉพาะเจาะจง
3. มาสก์ & ตัวดำเนินการ Bitwise
MDN มีภาพรวมที่ดีของการทำงานของตัวดำเนินการ bitwise ที่สำคัญ:
ตัวดำเนินการ Bitwise ถือว่าตัวถูกดำเนินการของพวกเขาเป็นลำดับ32 บิต (ศูนย์และคน)
ก่อนการดำเนินการจะถูกนำไปใช้ตัวเลขจุดลอยตัว 64 บิตจะถูกแปลงเป็นจำนวนเต็ม 32 บิต หลังจากที่พวกเขาถูกแปลงกลับ
นี่คือตัวอย่างรหัส MDN สำหรับการแปลงตัวเลขเป็นสตริงแบบ 32 บิต
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 บิตในรูปแบบสมบูรณ์ทั้งสองดังนั้นวิธีการใด ๆ ที่ใช้การดำเนินงานบิต จำกัด ช่วงของการส่งออกไปยัง -2147483648 10 (-2 31 ) - 2147483647 10 (2 31 -1)
อย่างไรก็ตามหากการดำเนินงานค่าที่เหมาะสมจะหลีกเลี่ยงและ 64 บิตเป็นตัวแทนจุดลอยถูกเก็บรักษาไว้โดยใช้ดำเนินการทางคณิตศาสตร์เท่านั้นที่เราสามารถแปลงได้อย่างน่าเชื่อถือใด ๆจำนวนเต็มปลอดภัยถึง 64 บิตสองของสัญกรณ์ไบนารีสมบูรณ์ด้วยเครื่องหมายขยาย 53 บิต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}
สำหรับเบราว์เซอร์รุ่นเก่านั้นจะมี polyfills สำหรับฟังก์ชันและค่าต่อไปนี้:
ในฐานะโบนัสที่เพิ่มเข้ามาคุณสามารถรองรับ Radix ใด ๆ (2–36) หากคุณทำการแปลงส่วนเติมเต็มของทั้งสองเพื่อหาจำนวนลบใน⌈64 / log 2 (radix) ⌉หลักโดยใช้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
ในการสร้างสหภาพระหว่างที่Float64Array
และUint16Array
โปรดดูที่ของคำตอบนี้ประวัติการแก้ไข
-(2**53)-1
การ2**53-1
แทนเพียง-(2**31)
จะ2**31-1
เหมือนคำตอบอันนัน
วิธีแก้ปัญหาที่ฉันใช้กับ 32- บิตเป็นรหัสท้ายคำตอบซึ่งมาจาก developer.mozilla.org (MDN) แต่มีบางบรรทัดเพิ่มสำหรับ A) การจัดรูปแบบและ B) ตรวจสอบว่า ตัวเลขอยู่ในช่วง
บางคนแนะนำx.toString(2)
ว่ามันใช้ไม่ได้กับเชิงลบมันแค่แปะเครื่องหมายลบในนั้นสำหรับพวกเขาซึ่งไม่ดี
เฟอร์นันโดพูดถึงวิธีแก้ปัญหาง่ายๆ(x>>>0).toString(2);
ซึ่งใช้ได้กับฟิล์มเนกาทีฟ แต่มีปัญหาเล็กน้อยเมื่อ x เป็นบวก มันมีเอาต์พุตเริ่มต้นด้วย 1 ซึ่งสำหรับจำนวนบวกนั้นไม่เหมาะกับ 2s
ใครก็ตามที่ไม่เข้าใจความจริงของตัวเลขบวกเริ่มต้นด้วย 0 และจำนวนลบด้วย 1 ในส่วนเสริม 2s สามารถตรวจสอบ SO QnA นี้ได้ในส่วนเติมเต็ม 2s “ ส่วนประกอบของ 2” คืออะไร
วิธีแก้ปัญหาอาจเกี่ยวข้องกับการบวก 0 สำหรับจำนวนบวกซึ่งฉันทำในการแก้ไขคำตอบนี้ก่อนหน้านี้ และหนึ่งสามารถยอมรับบางครั้งมีหมายเลข 33 บิตหรือหนึ่งสามารถตรวจสอบให้แน่ใจว่าจำนวนการแปลงอยู่ในช่วง - (2 ^ 31) <= x <2 ^ 31-1 ดังนั้นจำนวนนั้นคือ 32 บิตเสมอ แต่แทนที่จะทำอย่างนั้นคุณสามารถไปกับวิธีแก้ปัญหานี้ใน mozilla.org
คำตอบและรหัสของ Patrick นั้นยาวและเห็นได้ชัดว่าใช้งานได้ 64- บิต แต่มีข้อผิดพลาดที่ผู้วิจารณ์พบและผู้วิจารณ์แก้ไขข้อผิดพลาดของ patrick แต่ Patrick มี "magic number" ในรหัสของเขาที่เขาไม่ได้แสดงความคิดเห็น ลืมเกี่ยวกับและแพทริคไม่เข้าใจรหัสของตัวเอง / ทำไมมันทำงาน
อันนันมีคำศัพท์ที่ไม่ถูกต้องและไม่ชัดเจน แต่ได้กล่าวถึงวิธีแก้ปัญหาโดย developer.mozilla.org https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators ซึ่งทำงานได้กับตัวเลข 32 บิต
รหัสมีขนาดกะทัดรัดสวยฟังก์ชั่นของสามบรรทัด
แต่ฉันได้เพิ่ม regex เพื่อจัดรูปแบบผลลัพธ์ในกลุ่ม 8 บิต ตามวิธีการพิมพ์ตัวเลขด้วยเครื่องหมายจุลภาคเป็นตัวคั่นหลักพันใน JavaScript (ฉันเพิ่งแก้ไขจากการจัดกลุ่มใน3s จากขวาไปซ้ายและเพิ่มเครื่องหมายจุลภาคเพื่อจัดกลุ่มใน8s จากขวาไปซ้ายและเพิ่มช่องว่าง )
และในขณะที่โมซิลล่าแสดงความคิดเห็นเกี่ยวกับขนาดของ nMask (จำนวนที่ป้อนเข้า) .. ว่ามันจะต้องอยู่ในช่วงพวกเขาไม่ได้ทดสอบหรือโยนข้อผิดพลาดเมื่อจำนวนอยู่นอกช่วงดังนั้นฉันจึงได้ เสริมว่า
ฉันไม่แน่ใจว่าทำไมพวกเขาตั้งชื่อพารามิเตอร์ของพวกเขาว่า 'nMask' แต่ฉันจะปล่อยไว้อย่างนั้น
การอ้างอิง: https://developer.mozilla.org/en-US/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.
*/