“ ส่วนประกอบของ 2” คืออะไร


434

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

ดังนั้นฉันต้องการเริ่มโพสต์วิกิชุมชนนี้เพื่อกำหนดว่า Complement ของ Two คืออะไรวิธีการใช้และวิธีที่จะมีผลกับตัวเลขระหว่างการดำเนินการเช่น cast (จากการเซ็นชื่อเป็น unsigned และกลับกัน), bit-wise และ bit-shift .

สิ่งที่ฉันหวังไว้คือคำจำกัดความที่ชัดเจนและรัดกุมซึ่งโปรแกรมเมอร์สามารถเข้าใจได้ง่าย

คำตอบ:


627

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

เพื่อให้เข้าใจคุณต้องคิดถึงตัวเลขเป็นเลขฐานสอง

มันพูดโดยทั่วไปว่า

  • สำหรับศูนย์ให้ใช้ 0 ทั้งหมด
  • สำหรับจำนวนเต็มบวกเริ่มต้นด้วยจำนวนสูงสุด 2 (จำนวนบิต - 1) -1
  • สำหรับจำนวนเต็มลบให้ทำสิ่งเดียวกัน แต่เปลี่ยนบทบาทเป็น 0 และ 1 (แทนการเริ่มต้นด้วย 0000 เริ่มต้นด้วย 1111 - นั่นคือส่วน "ส่วนประกอบ")

ลองด้วยมินิไบต์ 4 บิต (เราจะเรียกมันว่าnibble - 1/2 a byte)

  • 0000 - ศูนย์
  • 0001 - หนึ่ง
  • 0010 - สอง
  • 0011 - สาม
  • 0100เป็น0111สี่ถึงเจ็ด

นั่นคือเท่าที่เราสามารถบวกได้ 2 3 -1 = 7

สำหรับเชิงลบ:

  • 1111 - ลบหนึ่ง
  • 1110 - ลบสอง
  • 1101 - ลบสาม
  • 1100เป็น1000- ลบสี่ถึงลบแปด

โปรดทราบว่าคุณจะได้รับค่าเพิ่มเติมหนึ่งรายการสำหรับเชิงลบ ( 1000= -8) ที่คุณไม่ได้รับเพื่อผลบวก นี่เป็นเพราะ0000ใช้เป็นศูนย์ ซึ่งถือได้ว่าเป็นNumber Lineของคอมพิวเตอร์

แยกแยะระหว่างจำนวนบวกและลบ

การทำเช่นนี้บิตแรกจะได้รับบทบาทของ "เครื่องหมาย" บิตเนื่องจากสามารถใช้เพื่อแยกความแตกต่างระหว่างค่าทศนิยมแบบไม่ลบและลบ ถ้าบิตที่สำคัญที่สุดคือค่า1นั้นก็สามารถบอกได้ว่าเลขฐานสองเป็นลบโดยที่ถ้าบิตที่สำคัญที่สุด (ซ้ายสุด) คือ0คุณสามารถพูดได้ว่าค่าทศนิยมนั้นไม่ใช่ค่าลบ

ตัวเลขลบ "หนึ่งของ" ลบเพียงแค่เครื่องหมายบิตจากนั้นนับจาก 0 แต่วิธีนี้มีการจัดการกับการตีความ1000ว่า "ศูนย์ลบ" ซึ่งทำให้เกิดความสับสน โดยทั่วไปคุณต้องกังวลเกี่ยวกับเรื่องนี้เมื่อทำงานใกล้กับฮาร์ดแวร์


146
ส่วนที่ดีที่สุดของส่วนประกอบสองอาจเป็นวิธีที่ทำให้คณิตศาสตร์ง่ายขึ้น ลองเพิ่ม 2 (0010) และ -2 (1110) เข้าด้วยกันและคุณจะได้รับ 10,000 บิตที่สำคัญที่สุดคือล้นดังนั้นผลที่ได้คือ 0000 จริง ๆ แล้วคล้ายกับเวทมนตร์ 2 + -2 = 0
Naaff

96
ข้อได้เปรียบอีกอย่างหนึ่งนอกเหนือจากการเพิ่มและการลบง่าย ๆ คือการเติมเต็ม 2s นั้นมีเพียงศูนย์เดียว หากคุณกำลังใช้บิตสัญญาณอย่างง่ายพูดโดยใช้ 0001 เพื่อเป็นตัวแทน +1 และ 1001 เพื่อเป็นตัวแทน -1 คุณจะมีสองศูนย์: 0000 ("+0") และ 1,000 ("-0") นั่นเป็นความเจ็บปวดที่แท้จริงในด้านหลัง
Jörg W Mittag

26
โหวตขึ้นเพราะมันเป็นประเด็นและอธิบายว่าทำไมค่าลบมีช่วงใหญ่กว่าค่าบวก ฉันมาหาสาเหตุของความแตกต่างของช่วง
Ashwin

2
คุณไม่ควรพูดว่า "สำหรับจำนวนเต็มลบให้ทำสิ่งเดียวกัน แต่นับถอยหลังและสลับบทบาทของ 0 และ 1 ของ"
Koray Tugay

1
ดีเลิศเพิ่มส่วนพิเศษของการแปลงบิตเป็นจำนวนเต็มลบ
Suraj Jain

339

ฉันสงสัยว่าสามารถอธิบายได้ดีกว่าบทความ Wikipedia หรือไม่

ปัญหาพื้นฐานที่คุณพยายามแก้ไขด้วยการแสดงส่วนประกอบสองอย่างคือปัญหาการจัดเก็บจำนวนเต็มลบ

ก่อนอื่นให้พิจารณาจำนวนเต็มที่ไม่ได้ลงนามที่เก็บไว้ใน 4 บิต คุณสามารถมีดังต่อไปนี้

0000 = 0
0001 = 1
0010 = 2
...
1111 = 15

สิ่งเหล่านี้ไม่ได้ลงชื่อเนื่องจากไม่มีข้อบ่งชี้ว่าพวกมันเป็นลบหรือบวก

เครื่องหมายขนาดและสัญกรณ์ส่วนเกิน

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

0000 = +0
0001 = +1
0010 = +2
...
1000 = -0
1001 = -1
1111 = -7

ดังนั้นคุณเห็นปัญหาที่นั่น? เรามีค่าบวกและลบ 0 ปัญหาที่ใหญ่กว่าคือการบวกและลบเลขฐานสอง วงจรที่จะเพิ่มและลบโดยใช้ขนาดสัญญาณจะซับซ้อนมาก

คืออะไร

0010
1001 +
----

?

ระบบก็คือสัญกรณ์ส่วนเกิน คุณสามารถเก็บตัวเลขติดลบคุณกำจัดปัญหาสองศูนย์ แต่การบวกและการลบยังคงยาก

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

แปลงทศนิยมให้เป็นแบบสองส่วน

  1. แปลงตัวเลขเป็นไบนารี่ (ไม่ต้องสนใจเครื่องหมายตอนนี้) เช่น 5 คือ 0101 และ -5 คือ 0101

  2. หากจำนวนเป็นจำนวนบวกคุณจะทำ เช่น 5 คือ 0101 ในไบนารีโดยใช้เครื่องหมายเสริมสอง

  3. หากจำนวนเป็นลบแล้ว

    3.1 ค้นหาส่วนประกอบ (invert 0's และ 1's) เช่น -5 คือ 0101 ดังนั้นการค้นหาส่วนประกอบเสริมคือ 1010

    3.2 เพิ่ม 1 เข้ากับส่วนเสริม 1010 + 1 = 1011 ดังนั้น -5 ในส่วนเติมเต็มของสองคือ 1011

แล้วถ้าคุณต้องการที่จะทำ 2 + (-3) เป็นเลขฐานสองล่ะ? 2 + (-3) คือ -1 คุณต้องทำอย่างไรถ้าคุณใช้ขนาดสัญญาณเพื่อเพิ่มตัวเลขเหล่านี้ 0010 + 1101 =?

การใช้ส่วนประกอบสองอย่างพิจารณาว่าง่ายแค่ไหน

 2  =  0010
 -3 =  1101 +
 -------------
 -1 =  1111

การแปลงส่วนประกอบสองอย่างเป็นทศนิยม

แปลง 1111 เป็นทศนิยม:

  1. จำนวนเริ่มต้นด้วย 1 ดังนั้นมันจึงเป็นลบเราจึงหาส่วนประกอบของ 1111 ซึ่งก็คือ 0000

  2. เพิ่ม 1 ถึง 0000 และเราได้รับ 0001

  3. แปลง 0001 เป็นทศนิยมซึ่งเป็น 1

  4. ใช้เครื่องหมาย = -1

Tada!


45
คำตอบที่ดีที่สุดในความคิดของฉัน
Koray Tugay

5
ใช่แล้วอันนี้ค่อนข้างเรียบง่ายและอธิบายเรื่องนี้ได้ดีมาก
Max Koretskyi

3
ฉันไม่เข้าใจวิธีการเพิ่มเมื่อแปลงทั้งสองวิธีจะนำไปสู่หมายเลขเดียวกันเสมอ ในใจของฉันคุณจะย้อนกลับขั้นตอนหรือลบอย่างใดอย่างหนึ่ง
Marcos Pereira

2
ทำไมต้องเพิ่ม 1 ในส่วนประกอบ
Zinan Xing

4
คำตอบนี้ควรใช้กับ Wikipedia
ฮิโระกิ

119

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

จำวิธีการทำงานสำหรับทศนิยม:
  2345
เป็นวิธีการเขียน
  2 × 10 3 + 3 × 10 2 + 4 × 10 1 + 5 × 10 0

ในทางเดียวกันไบนารีเป็นวิธีการเขียนตัวเลขโดยใช้เพียง0และ1ตามแนวคิดทั่วไปเดียวกัน แต่แทนที่ 10s ข้างต้นด้วย 2s จากนั้นในไบนารี่
  1111
คือวิธีเขียน
  1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0
และถ้าคุณคิดออกมันจะกลายเป็น 15 (ฐาน 10) นั่นเป็นเพราะมันคือ
  8 + 4 + 2 + 1 = 15

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

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

โชคดีที่คอมพิวเตอร์ไม่ได้หมายถึงอนันต์ ตัวเลขถูกจำกัดความยาวเฉพาะ (หรือความกว้างหากคุณต้องการ) งั้นลองกลับไปหาเลขฐานสองบวก, แต่ด้วยขนาดที่เจาะจง ฉันจะใช้ 8 หลัก ("บิต") สำหรับตัวอย่างเหล่านี้ ดังนั้นเลขฐานสองของเราจะเป็น
  00001111
หรือ
  0 × 2 7 + 0 × 2 6 + 0 × 2 5 + 0 × 2 4 + 1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0

ในการสร้างลบส่วนเติมเต็ม 2 ของอันดับแรกเราจะเติมเต็มหลัก (ไบนารี) ทั้งหมดในรูปแบบ
  11110000
และเพิ่ม 1 ในรูปแบบ
  11110001
แต่เราจะเข้าใจได้อย่างไรว่าหมายถึง -15?

คำตอบคือเราเปลี่ยนความหมายของบิตลำดับสูง (ซ้ายสุด) บิตนี้จะเป็น1สำหรับจำนวนลบทั้งหมด การเปลี่ยนแปลงจะเป็นการเปลี่ยนสัญลักษณ์ของการมีส่วนร่วมกับค่าของตัวเลขที่ปรากฎดังนั้นตอนนี้เราเข้าใจว่า11110001เป็นตัวแทน
  - 1 × 2 7 + 1 × 2 6 + 1 × 2 5 + 1 × 2 4 + 0 × 2 3 + 0 × 2 2 + 0 × 2 1 + 1 × 2 0
ขอให้สังเกตว่า "-" ต่อหน้านิพจน์นั้น? หมายความว่าสัญญาณบิตมีน้ำหนัก -2 7นั่นคือ -128 (ฐาน 10) ตำแหน่งอื่น ๆ ทั้งหมดยังคงมีน้ำหนักเท่ากันกับที่มีในเลขฐานสองที่ไม่ได้ลงนาม

จากการ คำนวณ-15 ของเรามันคือ
  -128 + 64 + 32 + 16 + 1
ลองใช้เครื่องคิดเลขของคุณ มันคือ -15

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

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

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


1
ฉันชอบคำตอบนี้! อธิบายวิธีการเสริม 2s และเพิ่มผลงานหนึ่งชิ้น
SJ

ฉันชอบคำตอบนี้เช่นกัน โดยเฉพาะอย่างยิ่งที่คุณแสดงว่าจำนวนลบเป็นอย่างไร ที่นี่ฉันคิดว่าจำนวนทั้งหมดเป็นฤ,ษีไม่ใช่แค่ MSB แล้วบวกกลับค่าน้ำหนักอื่น ๆ ขอบคุณสิ่งนี้แก้บล็อกสมองของฉัน
user188757

งานที่ดีพูดถึงหมายเลขคี่บอลที่ไม่มีอินเวอร์ส แต่เราจะทำอย่างไรกับเรื่องนี้ เราเพิ่งตั้งค่าสถานะโอเวอร์โฟลว์หากมีคนพยายามที่จะกลับด้านหรือไม่?
นิวแฮมป์เชียร์

ในขณะที่คำตอบอื่น ๆ ให้ความสำคัญกับ "วิธีการ" คำตอบนี้จะนำเราเบา ๆ กับ "ทำไม" มันช่วยฉัน ขอบคุณ!
Abhishek Pathak

หากตัวเลขลงท้ายด้วย 11,000 ... 000 การสลับกลับจะให้ผลตอบแทน 1,000 ... 000 สัญกรณ์ประกอบสองจะขึ้นอยู่กับความคิดที่ว่าตัวเลขทั้งหมดทางด้านซ้ายของหลักที่เป็นตัวแทนซ้ายสุดควรมีค่าเช่นเดียวกับตัวเลขนั้น แต่เมื่อแปลงกลับตัวเลขที่มีค่าเป็น 1,000 ... 000 นั่นจะไม่เป็นจริง
supercat

20

ส่วนประกอบที่ 2 มีประโยชน์อย่างมากสำหรับการค้นหาค่าของไบนารีอย่างไรก็ตามฉันคิดว่าวิธีที่กระชับกว่านี้ในการแก้ปัญหาดังกล่าว (ไม่เคยเห็นใครประกาศเลย):

ใช้ไบนารีตัวอย่างเช่น: 1101 ซึ่งเป็น [สมมติว่าพื้นที่ที่ "1" เป็นสัญญาณ] เท่ากับ-3

ใช้ส่วนประกอบ 2 ที่เราจะทำ ... พลิก 1101 ถึง 0010 ... เพิ่ม 0001 + 0010 ===> ให้เรา 0011 0011 เป็นเลขฐานสองบวก = 3 ดังนั้น 1101 = -3 !

สิ่งที่ฉันรู้:

แทนที่จะเป็นการพลิกและการเพิ่มคุณสามารถทำวิธีการพื้นฐานเพื่อแก้หาไบนารีที่เป็นบวก (สมมติว่า 0101) คือ (2 3 * 0) + (2 2 * 1) + (2 1 * 0) + (2 0 * 1) = 5

ทำสิ่งเดียวกันกับแนวคิดเชิงลบ! ​​(มีการบิดเล็กน้อย)

รับ 1101 ตัวอย่างเช่น:

สำหรับหมายเลขแรกแทน 2 3 * 1 = 8ทำ - (2 3 * 1) = -8

จากนั้นดำเนินการต่อตามปกติทำ-8 + (2 2 * 1) + (2 1 * 0) + (2 0 * 1) = -3


1
วิธีที่ดีที่สุดฉันสามารถเข้าใจส่วนประกอบ 2 ได้ หลังจากอ่านนี้ฉันสามารถเข้าใจคำตอบทั้งหมดของคำถามข้างต้น
Shakeel Shahzad

1
นี่คือวิธีการที่กล่าวถึงในหนังสือระบบคอมพิวเตอร์: มุมมองของโปรแกรมเมอร์
jimo

1
นี่เป็นวิธีที่เร็วกว่ามาก!
chanzerre

14

ลองนึกภาพว่าคุณมีจำนวนบิต / บิต / จำนวน / จำนวน จำกัด คุณกำหนด 0 เป็นตัวเลขทั้งหมดเป็น 0 และนับขึ้นตามธรรมชาติ:

00
01
02
..

ในที่สุดคุณจะล้น

98
99
00

เรามีตัวเลขสองหลักและสามารถแทนตัวเลขทั้งหมดได้ตั้งแต่ 0 ถึง 100 ตัวเลขทั้งหมดนั้นเป็นค่าบวก! สมมติว่าเราต้องการแสดงตัวเลขติดลบเช่นกัน?

สิ่งที่เรามีคือวัฏจักร ตัวเลขก่อนหน้า 2 คือ 1 หมายเลขก่อนหน้า 1 คือ 0 หมายเลขก่อนหน้าคือ 0 ... 99 99

สมมติว่าจำนวนใด ๆ ที่มากกว่า 50 เป็นลบ "0" ถึง "49" แทน 0 ถึง 49 "99" คือ -1, "98" คือ -2, ... "50" คือ -50

การแสดงนี้เป็นส่วนเติมเต็มสิบ คอมพิวเตอร์มักใช้ส่วนประกอบสองอย่างอย่างซึ่งเหมือนกันยกเว้นการใช้บิตแทนตัวเลข

สิ่งที่ดีเกี่ยวกับการเติมเต็มสิบคือนอกจากที่เพิ่งทำงาน คุณไม่จำเป็นต้องทำอะไรเป็นพิเศษเพื่อเพิ่มจำนวนบวกและลบ!


9

ฉันอ่านคำอธิบายที่ยอดเยี่ยมเกี่ยวกับ Redditโดย jng โดยใช้เครื่องวัดระยะทางเป็นแบบเปรียบเทียบ

ป้อนคำอธิบายรูปภาพที่นี่

มันเป็นแบบแผนที่มีประโยชน์ วงจรเดียวกันและการดำเนินการเชิงตรรกะที่เพิ่ม / ลบจำนวนบวกในไบนารียังคงทำงานได้ทั้งในเชิงบวกและเชิงลบหากใช้การประชุมนั่นเป็นเหตุผลว่าทำไมมันจึงมีประโยชน์และอยู่ทั่วไปทุกหนทุกแห่ง

ลองนึกภาพมาตรวัดระยะทางของรถยนต์มันหมุนไปที่ (พูด) 99999 ถ้าคุณเพิ่ม 00000 คุณจะได้รับ 00001 ถ้าคุณลด 00000 คุณจะได้ 99999 (เนื่องจากการหมุน) หากคุณเพิ่มหนึ่งกลับไปที่ 99999 มันจะกลับไปที่ 00000 ดังนั้นจึงเป็นประโยชน์ในการตัดสินใจว่า 99999 หมายถึง -1 ในทำนองเดียวกันมันมีประโยชน์มากในการตัดสินใจว่า 99998 หมายถึง -2 และอื่น ๆ คุณต้องหยุดที่ใดที่หนึ่งและโดยการประชุมครึ่งแรกของตัวเลขถือว่าเป็นลบ (50,000-99,999) และครึ่งล่างนั้นเป็นเพียงการยืน (00000-49999) ดังนั้นตัวเลขบนสุดคือ 5-9 หมายถึงตัวเลขที่แสดงนั้นเป็นค่าลบและเป็น 0-4 หมายถึงตัวเลขที่แสดงนั้นเป็นค่าบวก - เหมือนกับบิตบนสุดที่แสดงเครื่องหมายในเลขฐานสองของทั้งสอง

การเข้าใจสิ่งนี้ก็ยากสำหรับฉันเช่นกัน เมื่อฉันได้รับมันและกลับไปอ่านบทความและคำอธิบายหนังสืออีกครั้ง (ไม่มีอินเทอร์เน็ตในตอนนั้น) มันกลายเป็นว่ามีคนมากมายที่อธิบายว่าไม่ได้เข้าใจจริงๆ ฉันเขียนภาษาแอสเซมบลีการสอนหนังสือหลังจากนั้น (ซึ่งขายได้ค่อนข้างดีเป็นเวลา 10 ปี)


5

พบสองส่วนเติมเต็มด้วยการบวกหนึ่งส่วนเสริมของจำนวนที่กำหนด ให้บอกว่าเราต้องหาส่วนประกอบสองอย่างจาก10101นั้นหาส่วนประกอบที่สมบูรณ์นั่นคือ01010เพิ่ม1ในผลลัพธ์นี้นั่นคือ01010+1=01011ซึ่งเป็นคำตอบสุดท้าย


4

ให้คำตอบ 10 - 12 ในรูปแบบไบนารีโดยใช้ 8 บิต: สิ่งที่เราจะทำคือ 10 + (-12)

เราจำเป็นต้องได้รับส่วนชมเชยจาก 12 เพื่อลบออกจาก 10 12 ในไบนารีคือ 00001100 10 ในไบนารีคือ 00001010

เพื่อให้ได้คำชมเชยจาก 12 เราแค่ย้อนกลับบิตทั้งหมดแล้วบวก 1 12 ในการกลับไบนารี่เป็น 11110011 นอกจากนี้ยังเป็นรหัสผกผัน ตอนนี้เราต้องเพิ่มอันใหม่ซึ่งตอนนี้คือ 11110100

ดังนั้น 11110100 จึงเป็นคำชมจาก 12! ง่ายเมื่อคุณคิดถึงวิธีนี้

ตอนนี้คุณสามารถแก้ปัญหาข้างต้นของ 10 - 12 ในรูปแบบไบนารี

00001010
11110100
-----------------
11111110  

3

2's Complements: เมื่อเราเพิ่มหนึ่งพิเศษด้วยการเติมตัวเลข 1 เราจะได้รับการเติม 2 ตัวอย่างเช่น: 100101 เป็นส่วนประกอบ 1 ของคือ 011010 และส่วนประกอบ 2 ของคือ 011010 + 1 = 011011 (โดยการเพิ่มหนึ่งรายการด้วยส่วนประกอบ 1 ของ) สำหรับข้อมูลเพิ่มเติม บทความนี้อธิบายแบบกราฟิก


เครื่องหมายบวก 1 สำหรับลิงก์ที่มีคำอธิบายวงกลม
Manohar Reddy Poreddy

3

เมื่อมองไปที่ระบบประกอบของทั้งสองจากมุมมองทางคณิตศาสตร์มันสมเหตุสมผลจริงๆ ในส่วนสิบของความคิดคือการ 'แยก' ความแตกต่างเป็นหลัก

ตัวอย่าง: 63 - 24 = x

เราเพิ่มส่วนเติมเต็มของ 24 ซึ่งเป็นจริงเพียง (100 - 24) สิ่งที่เราทำคือเพิ่ม 100 ทั้งสองข้างของสมการ

ตอนนี้สมการคือ: 100 + 63 - 24 = x + 100 นั่นคือสาเหตุที่เราลบ 100 (หรือ 10 หรือ 1,000 หรืออะไรก็ตาม)

เนื่องจากสถานการณ์ที่ไม่สะดวกที่จะลบจำนวนหนึ่งจากสายโซ่ยาวของศูนย์เราจึงใช้ระบบ 'ส่วนเสริมรังสีที่ลดลง' ในระบบเลขฐานสิบส่วนประกอบเก้าส่วน

เมื่อเรานำเสนอด้วยจำนวนลบออกจากห่วงโซ่ขนาดใหญ่ของเก้าเราเพียงแค่ต้องย้อนกลับตัวเลข

ตัวอย่าง: 99999 - 03275 = 96724

นั่นคือเหตุผลหลังจากส่วนประกอบเก้าตัวเราเพิ่ม 1 อย่างที่คุณอาจรู้จากคณิตศาสตร์ในวัยเด็ก 9 กลายเป็น 10 โดย 'ขโมย' 1 ดังนั้นโดยพื้นฐานแล้วมันเป็นแค่ส่วนประกอบสิบตัวที่ใช้ 1 จากความแตกต่าง

ใน Binary ส่วนประกอบสองอย่างนั้นเทียบเท่ากับส่วนประกอบสิบส่วนในขณะที่ส่วนประกอบหนึ่งประกอบกับส่วนประกอบเก้าส่วน ความแตกต่างหลักคือแทนที่จะพยายามแยกความแตกต่างกับพลังของสิบ (เพิ่ม 10, 100, ฯลฯ เข้าไปในสมการ) เรากำลังพยายามแยกความแตกต่างกับพลังของทั้งสอง

ด้วยเหตุผลนี้เองที่เรากลับด้าน เช่นเดียวกับวิธีการ minuend ของเราเป็นห่วงโซ่ของเก้าเป็นทศนิยม minuend ของเราเป็นห่วงโซ่ของคนในไบนารี

ตัวอย่าง: 111111 - 101001 = 010110

เนื่องจากกลุ่มของโซ่มีค่าต่ำกว่าพลังที่ดีของทั้งสองพวกเขาจึง 'ขโมย' 1 จากความแตกต่างอย่างที่เก้าทำในรูปทศนิยม

เมื่อเราใช้เลขฐานสองเป็นลบเราแค่พูดว่า:

0000 - 0101 = x

1111 - 0101 = 1010

1111 + 0000 - 0101 = x + 1111

ในการ 'แยก' x เราต้องเพิ่ม 1 เพราะ 1111 อยู่ห่างจาก 10,000 และเราลบ 1 นำออกเพราะเราเพิ่งเพิ่มเข้าไปในความแตกต่างเดิม

1111 + 1 + 0000 - 0101 = x + 1111 + 1

10000 + 0000 - 0101 = x + 10,000

เพียงแค่นำ 10000 ออกจากทั้งสองข้างเพื่อให้ได้ x นั่นคือพีชคณิตพื้นฐาน


3

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

ความสับสนนั้นมาจากความเข้าใจที่ไม่ดีของคำจำกัดความของจำนวนส่วนประกอบ ส่วนประกอบคือส่วนที่ขาดหายไปซึ่งจะทำให้บางสิ่งเสร็จสมบูรณ์

การรวม Radix ของตัวเลข n หลัก x ใน Radix b คือตามนิยาม, b ^ nx ในไบนารี 4 แทนด้วย 100 ซึ่งมี 3 หลัก (n = 3) และ radix ของ 2 (b = 2) ดังนั้นส่วนประกอบของ radix คือ b ^ nx = 2 ^ 3-4 = 8-4 = 4 (หรือ 100 ในหน่วยไบนารี)

อย่างไรก็ตามในการรับเลขฐานสองของเลขฐานสองนั้นไม่ใช่เรื่องง่ายเท่ากับการได้ส่วนเติมเต็มที่ลดลงซึ่งนิยามว่า (b ^ n-1) ในการรับส่วนเสริม Radix ที่ลดลงคุณเพียงแค่พลิกตัวเลขทั้งหมด

100 -> 011 (ส่วนเสริม Radix ลดลง (หนึ่งส่วน))

เพื่อให้ได้ส่วนเสริม radix (สองตัว) เราก็บวก 1 ตามที่นิยามไว้

011 +1 -> 100 (ส่วนประกอบสองอย่าง)

ตอนนี้ด้วยความเข้าใจใหม่นี้มาดูตัวอย่างของ Vincent Ramdhanie (ดูคำตอบที่สองด้านบน)

/ * จุดเริ่มต้นของ Vincent

แปลง 1111 เป็นทศนิยม:

จำนวนเริ่มต้นด้วย 1 ดังนั้นมันจึงเป็นลบเราจึงหาส่วนประกอบของ 1111 ซึ่งก็คือ 0000 เพิ่ม 1 ถึง 0000 และเราได้รับ 0001 แปลง 0001 เป็นทศนิยมซึ่งก็คือ 1 ใช้เครื่องหมาย = -1 Tada!

ในตอนท้ายของ Vincent * /

ควรจะเข้าใจว่าเป็น

จำนวนเริ่มต้นด้วย 1 ดังนั้นมันจึงเป็นลบ เรารู้ว่ามันเป็นการรวมกันของสองค่า x ในการค้นหา x ที่แทนด้วยส่วนประกอบสองตัวอันดับแรกเราต้องหาส่วนประกอบที่ 1 ของมันก่อน

สององค์ประกอบของ x: 1111 หนึ่งส่วนประกอบของ x: 1111-1 -> 1110; x = 0001, (พลิกทุกหลัก)

ใช้เครื่องหมาย - และ answer = -x = -1


3

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

                  35=035=000000035.

ในที่เก็บข้อมูลคอมพิวเตอร์ไม่มีที่ว่าง บิตทั้งหมด (เลขฐานสอง) ต้องเป็น 0 หรือ 1 หากต้องการใช้หมายเลขหน่วยความจำอย่างมีประสิทธิภาพอาจถูกเก็บไว้เป็น 8 บิต, 16 บิต, 32 บิต, 64 บิต, 128 บิต เมื่อหมายเลขที่เก็บไว้เป็นเลข 8 บิตถูกถ่ายโอนไปยังตำแหน่ง 16 บิตเครื่องหมายและขนาด (ค่าสัมบูรณ์) จะต้องยังคงเหมือนเดิม ทั้งส่วนประกอบ 1 และส่วนประกอบ 2 ช่วยอำนวยความสะดวกในเรื่องนี้ คำนาม: คอมพลีเมนต์ของทั้ง 1 และคอมพลีเมนต์ของ 2 เป็นการแทนเลขฐานสองของปริมาณที่เซ็นชื่อซึ่งบิตที่สำคัญที่สุด (อันที่อยู่ทางซ้าย) คือบิตของเครื่องหมาย 0 มีค่าเป็นบวกและ 1 เป็นค่าลบ ส่วนประกอบ 2s ไม่ได้หมายถึงเชิงลบ. มันหมายถึงปริมาณที่ลงนาม ในรูปของทศนิยมขนาดจะแสดงเป็นปริมาณบวก โครงสร้างใช้ส่วนขยายสัญญาณเพื่อรักษาปริมาณเมื่อส่งเสริมการลงทะเบียน [] ด้วยบิตเพิ่มเติม:

       [0101]=[00101]=[00000000000101]=5 (base 10)
       [1011]=[11011]=[11111111111011]=-5(base 10)

ในฐานะที่เป็นคำกริยา: 2 สมบูรณ์วิธีการปฏิเสธ มันไม่ได้แปลว่าทำให้เป็นลบ มันหมายความว่าถ้าลบทำให้เป็นบวก ถ้าบวกให้ลบ ขนาดเป็นค่าสัมบูรณ์:

        if a >= 0 then |a| = a
        if a < 0 then |a| = -a = 2scomplement of a

ความสามารถนี้ช่วยให้การลบแบบไบนารีที่มีประสิทธิภาพโดยใช้ negate นั้นเพิ่ม a - b = a + (-b)

วิธีการอย่างเป็นทางการในการนำส่วนประกอบ 1 มาใช้สำหรับแต่ละหลักลบค่าจาก 1

        1'scomp(0101) = 1010.

สิ่งนี้เหมือนกับการพลิกหรือสลับกลับทีละบิต ซึ่งส่งผลให้เกิดศูนย์ลบซึ่งไม่เป็นที่ชื่นชอบดังนั้นการเพิ่มส่วนประกอบหนึ่งเข้าไปใน te 1 จะช่วยขจัดปัญหาได้ หากต้องการลบล้างหรือเติมเต็ม 2s ก่อนอื่นให้เติม 1s จากนั้นบวก 1

        Example 1                             Example 2
         0101  --original number              1101
         1's comp  1010                       0010
         add 1     0001                       0001
         2's comp  1011  --negated number     0011

ในตัวอย่างการปฏิเสธใช้งานได้ดีกับเครื่องหมายที่ขยายจำนวน

การเพิ่ม:
1110 Carry 111110 Carry 0110 เหมือนกับ 000110 1111 111111 sum 0101 sum 000101

การลบ:

    1110  Carry                      00000   Carry
     0110          is the same as     00110
    -0111                            +11001
  ----------                        ----------
sum  0101                       sum   11111

โปรดสังเกตว่าเมื่อทำงานกับส่วนประกอบ 2 ของพื้นที่ว่างทางด้านซ้ายของตัวเลขจะเต็มด้วยศูนย์สำหรับตัวเลขบวก แต่เต็มไปด้วยตัวเลขสำหรับจำนวนลบ นำติดตัวเพิ่มเสมอและจะต้องเป็น 1 หรือ 0

ไชโย


3

ส่วนประกอบของ 2 นั้นเป็นวิธีที่จะเกิดขึ้นกับค่าผกผันของเลขฐานสอง ถามตัวคุณเองว่า: เมื่อกำหนดตัวเลขในรูปแบบไบนารีรูปแบบบิตใดเมื่อเพิ่มไปยังหมายเลขเดิมจะทำให้ผลลัพธ์เป็นศูนย์ หากคุณสามารถใช้รูปแบบบิตนี้ได้รูปแบบบิตนั้นจะเป็นตัวแทน -ve (การเพิ่มค่าผกผัน) ของหมายเลขดั้งเดิม ตามคำจำกัดความการเพิ่มจำนวนลงในค่าผกผันเพิ่มเติมควรส่งผลให้เกิดศูนย์ ตัวอย่าง: ใช้ 101 ซึ่งเป็นทศนิยม 5 ตอนนี้งานที่จะเกิดขึ้นกับรูปแบบบิตซึ่งเมื่อเพิ่มลงในรูปแบบบิตที่กำหนด (101) จะส่งผลให้ศูนย์ โดยเริ่มจากบิตที่ถูกต้องที่สุดคือ 101 และสำหรับแต่ละบิตถามคำถามเดียวกันอีกครั้ง: ฉันควรเพิ่มบิตใดในบิตนี้เพื่อให้ผลลัพธ์เป็นศูนย์ ดำเนินการต่อโดยคำนึงถึงการดำเนินการตามปกติ หลังจากที่เราทำกับสถานที่ที่เหมาะสมที่สุด 3 แห่ง (ตัวเลขที่กำหนดหมายเลขเดิมโดยไม่คำนึงถึงศูนย์นำหน้า) การกระทำสุดท้ายจะเป็นรูปแบบบิตของการผกผันเพิ่มเติม นอกจากนี้เนื่องจากเราสามารถถือตัวเลขเดิมเป็นไบต์เดียวบิตนำอื่น ๆ ทั้งหมดในการเพิ่มค่าผกผันควรเป็น 1 ดังนั้นเมื่อคอมพิวเตอร์เพิ่มจำนวนและเพิ่มการใช้ "ที่" ประเภทการจัดเก็บ (ถ่าน) ผลลัพท์ใน char นั้นจะเป็นศูนย์ทั้งหมด

 1 1 1
 ----------
   1 0 1
 1 0 1 1 ---> additive inverse
  ---------
   0 0 0

2

ฉันชอบคำตอบของ lavinio แต่การขยับบิตเพิ่มความซับซ้อน บ่อยครั้งที่มีตัวเลือกของบิตเคลื่อนไหวในขณะที่เคารพบิตหรือในขณะที่ไม่เคารพบิต นี่เป็นตัวเลือกระหว่างการปฏิบัติกับตัวเลขตามที่ลงนาม (-8 ถึง 7 สำหรับแทะ, -128 ถึง 127 สำหรับไบต์) หรือหมายเลขที่ไม่ได้ลงชื่อแบบเต็มช่วง (0 ถึง 15 สำหรับนิพพาน, 0 ถึง 255 สำหรับไบต์)


2

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

ดังนั้นในส่วนเติมเต็มของ 2 หากหนึ่งคือ 0x0001 ดังนั้น -1 คือ 0x1111 เพราะนั่นจะส่งผลให้ผลรวมรวมของ 0x0000 (ที่มีมากเกิน 1)


1

ฉันมีปัญหาเดียวกันเมื่อสองสามสัปดาห์ที่ผ่านมา ฉันลงเอยด้วยการอ่านออนไลน์เกี่ยวกับเรื่องนี้จากแหล่งต่าง ๆ พยายามรวบรวมชิ้นส่วนและเขียนด้วยตัวเองเพียงเพื่อให้แน่ใจว่าฉันเข้าใจถูกต้อง เราใช้ส่วนประกอบสองอย่างโดยส่วนใหญ่ด้วยเหตุผลสองประการ:

  1. เพื่อหลีกเลี่ยงการแทนค่าหลาย 0
  2. เพื่อหลีกเลี่ยงการติดตามการพกบิต (ในส่วนเสริม) ในกรณีที่มีการไหลล้น
  3. ดำเนินการอย่างง่ายเช่นการบวกและการลบกลายเป็นเรื่องง่าย

หากคุณต้องการคำอธิบายรายละเอียดของเรื่องที่อยู่ในมือลองบทความที่เขียนโดยฉันที่นี่ หวังว่ามันจะช่วย!


1

ส่วนประกอบสองอย่างเป็นวิธีหนึ่งในการแสดงจำนวนลบและคอนโทรลเลอร์และโปรเซสเซอร์ส่วนใหญ่เก็บหมายเลขติดลบในรูปแบบประกอบ 2


1
สิ่งนี้จะไม่เพิ่มข้อมูลใด ๆ ลงในข้อมูลที่ได้จากคำตอบอื่น ๆ
Adrian Mole

0

การอ้างอิง: https://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html

ฉันกลับบิตทั้งหมดและเพิ่ม 1 โดยทางโปรแกรม:

  // in C++11
  int _powers[] = {
      1,
      2,
      4,
      8,
      16,
      32,
      64,
      128
  };

  int value=3;
  int n_bits=4;
  int twos_complement = (value ^ ( _powers[n_bits]-1)) + 1;

แม้แต่แอสเซมเบลอร์ก็จะอยู่ในระดับสูงเกินไป จำเป็นต้องดูแผนผังเกตระดับตรรกะเพิ่มเติม ด้วย T รอบ คุณมีอัลกอริทึมที่ถูกต้อง
mckenzm

0

2 ส่วนเสริมของจำนวนที่กำหนดคือเลขที่ ได้โดยการเพิ่ม 1 กับ 1 สมบูรณ์ของหมายเลข สมมติว่าเรามีเลขฐานสอง: 10111001101 ส่วนประกอบ 1 ของคือ: 01000110010 และส่วนประกอบ 2 ของจะเป็น: 01000110011


0

การเติมบิตเป็นจำนวนมากคือการพลิกบิตทั้งหมดในนั้น เพื่อเสริมสองอย่างเราพลิกบิตทั้งหมดแล้วบวกหนึ่งส่วน

การใช้การแทนค่าส่วนเสริม 2 สำหรับจำนวนเต็มที่ลงนามแล้วเราใช้การดำเนินการส่วนเสริม 2 เพื่อแปลงจำนวนบวกเป็นค่าลบติดลบและในทางกลับกัน ดังนั้นการใช้แทะสำหรับตัวอย่างเช่น0001(1) จะกลายเป็น1111(-1) และการประยุกต์ใช้ op 0001อีกครั้งกลับไป

พฤติกรรมของการดำเนินการที่ศูนย์มีประโยชน์ในการให้การเป็นตัวแทนเดียวสำหรับศูนย์โดยไม่ต้องจัดการกับศูนย์บวกและลบเป็นพิเศษ 0000เติมเต็ม1111ซึ่งเมื่อมีการเพิ่ม 1 ล้นไปสู่การ0000ให้เราหนึ่งศูนย์มากกว่าหนึ่งบวกและลบหนึ่ง

ข้อได้เปรียบที่สำคัญของการเป็นตัวแทนนี้คือวงจรเพิ่มมาตรฐานสำหรับจำนวนเต็มที่ไม่ได้ลงนามจะให้ผลลัพธ์ที่ถูกต้องเมื่อนำไปใช้กับพวกเขา ยกตัวอย่างเช่นการเพิ่มที่ 1 และ -1 ในแทะ: บิตล้นออกจากทะเบียนทิ้งไว้ข้างหลัง0001 + 11110000

สำหรับการแนะนำอ่อนโยนยอดเยี่ยม Computerphile ได้มีการผลิตวิดีโอเกี่ยวกับเรื่องนี้


0

ในระยะสั้น2's Complementเป็นวิธีการเก็บหมายเลขติดลบในหน่วยความจำคอมพิวเตอร์ ในขณะที่ตัวเลขบวกจะถูกเก็บไว้เป็นเลขฐานสองปกติ

ลองพิจารณาตัวอย่างนี้

คอมพิวเตอร์ใช้ Binary Number Systemเพื่อแสดงตัวเลขใด ๆ

x = 5;

สิ่งนี้แสดงว่า 0101นี้จะแสดงเป็น

x = -5;

เมื่อคอมพิวเตอร์เจอ -เข้าสู่ระบบจะคำนวณว่าเป็นส่วนประกอบ 2 และเก็บไว้ i.e5 = 0101 และเป็น 2 1011ส่วนเติมเต็มคือ

กฎสำคัญที่คอมพิวเตอร์ใช้ในการประมวลผลหมายเลขคือ

  1. ถ้าเป็นบิตแรก 1นั้นต้องเป็นnegativeตัวเลข
  2. หากบิตทั้งหมดยกเว้นบิตแรก0นั้นเป็นจำนวนบวกเพราะไม่มี-0ในระบบตัวเลข (1000 is not -0แทนเป็นบวก8)
  3. ถ้าบิตทั้งหมดเป็น 00แล้วมันเป็น
  4. positive numberอื่นมันเป็น


-6

คำตอบที่ง่ายที่สุด:

1111 + 1 = (1) 0000 ดังนั้น 1111 ต้องเป็น -1 จากนั้น -1 + 1 = 0

มันสมบูรณ์แบบที่จะเข้าใจสิ่งเหล่านี้ทั้งหมดสำหรับฉัน


สิ่งนี้ไม่ได้ให้คำตอบสำหรับคำถาม หากต้องการวิจารณ์หรือขอคำชี้แจงจากผู้แต่งโปรดแสดงความคิดเห็นใต้โพสต์ของพวกเขา
Codor

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