ฉันจะแปลงจำนวนเต็มเป็นไบนารีใน JavaScript ได้อย่างไร


299

ฉันต้องการดูจำนวนเต็มบวกหรือลบเป็นเลขฐานสอง

ค่อนข้างชอบคำถามนี้แต่สำหรับ JavaScript


2
ตัวอย่าง a.toString (2) ดูเหมือนจะใช้งานไม่ได้สำหรับ -1
barlop

1
นอกจากนี้ยังเป็นไปได้ที่จะแปลงจากเลขฐานสองเป็นทศนิยม: stackoverflow.com/questions/11103487/…
Anderson Green

และเมื่อฉันพูดว่า "เป็นไบนารี่" นั่นอาจจะคลุมเครือเล็กน้อย ฉันหมายถึงการเป็นตัวแทนบิตสตริงภายในซึ่งเป็นส่วนประกอบ 2s ดังนั้นจำนวนบวกจะอยู่ในฐาน 2 และมีเลข 0 นำหน้า (และจำนวนลบจะไม่ถูกเขียนด้วยสัญลักษณ์ลบหรือแสดงขนาดแทน แต่เป็น ฟังก์ชั่นของค่าบวกเชิงบวกของพวกเขา)
barlop

คำตอบ:


498
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


7
นี่คือคำอธิบาย
fernandosavio

รับในขณะที่ตั้งแต่ผมพยายามจาวาสคริปต์ แต่พยายามที่นี่w3schools.com/js/tryit.asp?filename=tryjs_output_alert กับเรื่องนี้ <script> window.alert ((- 3 >>> 0) .ToString (2)); </script> ใช่มันใช้ได้
barlop

1
toString (2) ไม่ทำงานเนื่องจากคุณได้รับอินพุตจากข้อความ ใช้สิ่งนี้: ฟังก์ชัน decToBase (ธันวาคม, ฐาน) {return parseInt (ธันวาคม) .toString (ฐาน); } การแจ้งเตือน (decToBase (ธันวาคม, 2));
หมอผี

คุณสมมติว่าอินพุตเป็นข้อความ แต่ฟังก์ชันในคำตอบคาดว่าจะเป็นจำนวนเต็ม ... ดังนั้นหากอินพุตเป็นข้อความเพียงแปลงเป็นจำนวนเต็มให้ใช้บิตปลอมและทำเสร็จแล้ว
fernandosavio

@Magus ผู้ที่รับอินพุตจากข้อความ!
barlop

207

ลอง

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);
    }
}

ฉันได้รับความช่วยเหลือจากที่นี่


ไม่ทำงานสำหรับ -1 A = -1; document.write (จำนวน (a.ToString (2))); แสดง -1
barlop

การอัพเดตยังคงไม่ทำงานสำหรับตัวเลขที่เป็นค่าลบ ( -3ส่งคืน1) นอกจากนี้ผมเชื่อว่าdec > 0ควรจะเป็นdec >= 0ซึ่งควรอย่างน้อยการแก้ไข 0. เพราะผลตอบแทนdec2Bin(0) 10
Adam Merrifield

ทั้งสองกรณีในความคิดเห็นด้านบนส่งคืนผลลัพธ์ที่ถูกต้องในคอนโซล Chrome ของฉัน - var a = -1; a.ToString (2); "-1" var a = -3; a.ToString (2); "-11"
Anmol Saraf

@ AmololSaraf ฉันเห็นสิ่งที่คุณหมายถึงและในขณะที่เรียกขานเมื่อคนพูดว่าอะไรคือ -5 ในทศนิยมและคำตอบคือ -5 เมื่อมันมาถึงตัวเลขติดลบในไบนารีในความรู้สึกใช่คุณสามารถติดเครื่องหมายลบที่นั่นดังนั้น 5 คือ 101 และ -5 คือ -101 แต่เนื่องจากคอมพิวเตอร์ไม่ได้เก็บเครื่องหมายลบมันก็แค่ 1 และ 0 ดังนั้นเมื่อเราบอกว่าจำนวนลบเป็นเลขฐานสองเราหมายถึงการใส่จำนวนลบ (รวมเครื่องหมายลบ) ใน 1s และ 0s วิธีการบางอย่างรวมถึงส่วนเสริม 1s ส่วนเติมเต็ม 2 และ 'เครื่องหมายและขนาด' ดังนั้น -101010101 หรือ -0101010 ไม่ใช่สิ่งที่ผู้คนหมายถึงด้วยจำนวนลบในเลขฐานสอง
barlop

ลิงค์นี้อาจเป็นที่สนใจของstackoverflow.com/questions/12337360/…อย่างไรก็ตามคำตอบของคุณขัดแย้งกับตัวเองคุณเขียนว่า "Javascript แทนเลขจำนวนเต็มฐานสองเชิงลบในรูปแบบสองส่วน" และรหัสของคุณบอกว่า "ที่นี่คุณสามารถแสดงตัวเลขในคำชม 2s แต่นี่ไม่ใช่สิ่งที่ JS ใช้เป็น [เหตุผลไร้สาระ]" และคุณก็ไม่มีการอ้างอิงเช่นกัน
barlop

53

ไบนารีใน 'แปลงเป็นไบนารี' สามารถอ้างถึงสามสิ่งหลัก ระบบตัวเลขตำแหน่งการแทนค่าฐานสองในหน่วยความจำหรือบิต 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 แบบง่าย (NUM) .toString (2)?
Magus

5
@ มากัสฉันคิดว่าฉันอธิบายความแตกต่างระหว่างตัวเลขและสตริงไบนารีได้เพียงพอ สตริงไบนารีแบบ 32 บิตมีความยาวสามสิบสองอักขระประกอบด้วย "1" และ "0" toString ส่งกลับจำนวนจริงที่แสดงโดยใช้ระบบจำนวนตำแหน่งที่มีฐานที่กำหนด มันขึ้นอยู่กับว่าทำไมคุณถึงต้องการสตริงมันมีความหมายต่างกันมาก
AnnanFay

ขอโทษคุณพูดถูก ฉันกระโดดตรงไปที่รหัส
Magus

1
มีปัญหากับ 0 นำหน้าโดยใช้วิธีการโพสต์อื่น ๆ (โดยเฉพาะกับหมายเลขนี้ 536870912, เลขศูนย์นำหน้าทั้งสองจะถูกลบออก) แต่วิธีนี้จัดการได้อย่างถูกต้อง
UberMouse

@UberMouse ใช่ >>> มีปัญหา 0s ชั้นนำฉันจะยอมรับเรื่องนี้
barlop

43

วิธีง่ายๆคือ ...

Number(42).toString(2);

// "101010"

24
ฉันต้องการ(42).toString(2)
Willem D'Haeseleer

33
หรือสั้นกว่านั้น42..toString(2)
kapex

9
ผู้คนกำลังดิ้นรนกับสิ่งนี้ คำตอบนั้นถูกต้องเพราะมันส่งสัญญาณอินพุต (42) ไปเป็นจำนวนเต็มและจำเป็นต้องใช้บรรทัดนั้น หากคุณได้รับ 'หมายเลข' จากการป้อนข้อความ toString (2) จะไม่ทำงาน
Magus

4
@ Kapep เพื่อนนั่นคืออัจฉริยะ คุณรู้เรื่องนี้ได้อย่างไร
Pacerier

2
@BatuG ไวยากรณ์สำหรับตัวเลขช่วยให้คุณสามารถละเว้นส่วนหลังตัวแยกทศนิยม คุณสามารถเขียน1.สิ่งที่เหมือนกับ1.0หรือเพียงแค่1(และในทำนองเดียวกันคุณสามารถละเว้นส่วนก่อนและเขียน.5แทน0.5) ดังนั้นในตัวอย่างจุดแรกคือตัวแยกทศนิยมซึ่งเป็นส่วนหนึ่งของตัวเลขและจุดที่สองคือตัวดำเนินการจุดสำหรับเรียกวิธีการกับหมายเลขนั้น คุณต้องใช้จุดสองจุด (หรือตัดจำนวนในวงเล็บ) และไม่สามารถเขียนได้เพียง42.toString(2)เพราะตัวแยกวิเคราะห์เห็นจุดเป็นตัวแยกทศนิยมและส่งข้อผิดพลาดเนื่องจากตัวดำเนินการจุดขาดหายไป
kapex

30

คำตอบนี้พยายามที่จะระบุที่อยู่อินพุตด้วยค่าสัมบูรณ์ในช่วง 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โปรดดูที่ของคำตอบนี้ประวัติการแก้ไข


ขอบคุณเป็นสิ่งที่ดีที่ใช้งานได้กับ 64 บิต .. คุณช่วยให้ฉันทราบข้อดีของคำตอบนี้ได้มากกว่าคำตอบของ annan หรือไม่?
barlop

2
ช่วงที่ใหญ่ขึ้นมาก? การทำงานสำหรับ-(2**53)-1การ2**53-1แทนเพียง-(2**31)จะ2**31-1เหมือนคำตอบอันนัน
Patrick Roberts

ใช่ว่าเป็นข้อได้เปรียบที่ยิ่งใหญ่ฉันได้รับสิ่งนั้นและมันจะทำอย่างไรแม้ว่ามันจะเป็นรหัสที่ค่อนข้างมาก แต่สิ่งที่ฉันหมายถึงคือฉันอยากรู้ว่าข้อดีอื่น ๆ ?
barlop

1
จาก 2 ** 32 + 1 on บิตสุดท้าย (ขวาสุด) จะถูกล้างเมื่อควรตั้งค่า
Lovro

1
ทำงานเมื่อสายคือ: exponent var = ((uint16 [3] & 0x7FF0) >> 4) - 1023 + 1;
Lovro

15

วิธีแก้ปัญหาที่ฉันใช้กับ 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"


8

คุณสามารถเขียนฟังก์ชันของคุณเองที่ส่งกลับอาร์เรย์จำนวนบิต ตัวอย่างวิธีการแปลงตัวเลขเป็นบิต

หาร | เงินปันผล | บิต / ที่เหลือ

2 | 9 | 1

2 | 4 | 0

2 | 2 | 0

~ | 1 | ~

ตัวอย่างของบรรทัดด้านบน: 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 ตรงกลางขึ้นไปด้านบน


1
Btw ทำไมคุณMath.floor(number%2)แทนnumber = Math.floor(number/2)?
Pacerier

1
เหตุผลคือตัวเลข% 2 ไม่เท่ากับตัวเลข / 2 เรามีความสนใจในส่วนที่เหลือไม่ใช่ความฉลาด
supritshah1289

0

ฉันใช้วิธีการที่แตกต่างกันเพื่อหาสิ่งที่ทำ ฉันตัดสินใจที่จะไม่ใช้รหัสนี้ในโครงการของฉัน แต่ฉันคิดว่าฉันจะทิ้งมันไว้ที่ไหนสักแห่งที่เกี่ยวข้องในกรณีที่มีประโยชน์สำหรับใครบางคน

  • ไม่ใช้การบีบบังคับแบบบิตหรือการบีบบังคับสองอย่าง
  • คุณเลือกจำนวนบิตที่ออกมา (ตรวจสอบค่าที่ถูกต้องของ '8', '16', '32' แต่ฉันคิดว่าคุณสามารถเปลี่ยนได้)
  • คุณเลือกว่าจะปฏิบัติต่อมันเป็นจำนวนเต็มที่ลงชื่อหรือไม่ได้ลงชื่อ
  • มันจะตรวจสอบปัญหาช่วงที่มีการรวมกันของการเซ็นชื่อ / unsigned และจำนวนบิตแม้ว่าคุณจะต้องการปรับปรุงการจัดการข้อผิดพลาด
  • นอกจากนี้ยังมีรุ่น "ย้อนกลับ" ของฟังก์ชันที่แปลงบิตกลับเป็น int คุณต้องใช้เนื่องจากอาจไม่มีอะไรอื่นที่จะตีความผลลัพธ์นี้: 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("---");


-1

อีกหนึ่งทางเลือก

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));

โปรดดูคำตอบของวินเซนต์และความคิดเห็นเกี่ยวกับมันมันจะนำไปใช้กับการโพสต์ของคุณด้วย
barlop

นี่คือสิ่งที่ถูกโพสต์ในความคิดเห็นเกี่ยวกับคำตอบของเขาโดยไม่เห็นด้วยและมีข้อตกลงบางอย่างจากคนอื่น ๆ "นั่นอาจเป็นประโยชน์สำหรับการศึกษาวิทยาศาสตร์คอมพิวเตอร์เพื่อดูวิธีทำด้วยตนเองเพื่อสอนตัวเอง แต่นั่นไม่ใช่สิ่งที่ฉัน ฉันกำลังถามว่าถ้าคุณจะสร้างล้อที่ทำด้วยตนเองเช่นนั้นอย่างน้อยก็ควรมีข้อได้เปรียบของประสิทธิภาพที่เพิ่มขึ้นหรือข้อดีบางอย่างเช่นการเพิ่มขนาดของค่าที่สามารถจัดการได้ฉันไม่เห็น การสนทนาใด ๆ จากคุณที่ระบุถึงความได้เปรียบเช่นนั้น "
barlop

นอกจากนี้วิธีการแก้ปัญหาของคุณล้มเหลวอย่างสมบูรณ์ก็ทำให้ตัวเลขในเชิงบวกเริ่มต้นด้วย 1 และล้มเหลวอย่างสมบูรณ์สำหรับตัวเลขลบและคำถามของฉันพูดถึงบวกหรือลบ
barlop

ดังนั้น "คำตอบ" ของคุณผิดในหลาย ๆ ระดับ และคุณควรทบทวนคำตอบอื่น ๆ ก่อนโพสต์คำตอบ
barlop

-2

นี่คือรหัสของฉัน:

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();

3
นั่นอาจเป็นประโยชน์สำหรับการศึกษาวิทยาศาสตร์คอมพิวเตอร์เพื่อดูวิธีการทำด้วยตนเองเพื่อสอนตัวเอง แต่นั่นไม่ใช่สิ่งที่ฉันขอ! หากคุณต้องการสร้างล้อใหม่ด้วยตนเองเช่นนั้นอย่างน้อยก็ควรมีข้อได้เปรียบในเรื่องประสิทธิภาพที่เพิ่มขึ้นหรือข้อดีบางประการเช่นการเพิ่มขนาดของค่าที่สามารถรับมือได้ ฉันไม่เห็นการสนทนาใด ๆ จากคุณที่ระบุถึงข้อได้เปรียบดังกล่าวที่นั่น
barlop

-3

นี่คือทางออก มันค่อนข้างง่ายตามความเป็นจริง

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.
        */

1
โซลูชันดังกล่าวได้รับการเสนอมาแล้วหลายครั้งและตามความเห็นของ OP แล้วในวันที่ 30 มีนาคม 2555 เวลา 9:01 น. ไม่สามารถใช้กับจำนวนลบได้
Adrian W

@AdrianW ฉันขอแนะนำให้ลงคะแนนนี้ ฉันสังเกตว่าคุณยังไม่ได้ อะไรที่ทำให้คุณต้องโหวตคำตอบ?
barlop
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.