DEV Community

Pramoth Suwanpech
Pramoth Suwanpech

Posted on

ทำไมตัวแปร Signed Integer ใช้ 2's complement

ในเลขฐานสิบเราใส่เครื่องหมายลบข้างหน้า เราเป็นมนุษย์เราก็เข้าใจได้ แต่ computer ต้องแปลงทุกสิ่งอย่างเป็นเลขฐานสองก่อน
จึงเกิดคำถามคือ เราจะแปลงเลขฐานสิบ Signed integer ไปเป็นเลขฐานสองอย่างไรดี จึงจะสามารถเอาเลขสองตัว (A และ -B) มาบวกกันแบบเลขฐานสองและสามารถแปลงกลับไปเป็นเลขฐานสิบได้ถูกต้อง โดยที่ไม่ต้องมีลอจิกพิเศษอะไรเพิ่มเติมและ space efficiency(เก็บค่าได้จำนวนมากสุด)

มีคนคิดหลายวิธี ข้อดีข้อเสียแตกต่างกันไป ผมจะนำเสนอสามวิธีที่มีคนคิดมาแล้ว ดังนี้

วิธีที่ 1.

เก็บโดยให้มี Signed bit เป็นสัญลักษณ์+- ไปเลย (Signed magnitude) เหมือนที่เราใช้ในเลขฐานสิบ โดยให้ Most sinificant bit(MSB) เป็น Sign bit เช่น 3 → 0011b ดังนั้น -3 ก็จะเป็น → 1011b 
ซึ่งแบบนี้มันดูเข้าใจง่ายสำหรับมนุษย์เลยแหละ แต่มันมีข้อเสีย 

  • มันมีศูนย์สองตัวคือ +0 และ -0 (0000b →+0 และ 1000b → -0)
  • 3+(-3) = 0 ใช่ไหม ไหนเราลองบวกมันหน่อยซิ
0011b  (3)
     +
1011b  (-3)
1110b ?? 3+(-3) = -5 แทนที่จะเป็น 0 ดังนั้นวิธีนี้ไม่เหมาะแล้ว
Enter fullscreen mode Exit fullscreen mode

วิธีที่ 2.

1's complement
ในวิธีที่ 1 เลขลบและเลขบวกเราแค่กลับบิตแรก(MSB) ส่วนวิธีนี้ให้กลับทุกบิต เช่น 3 --> 0011b ดังนั้น -3 --> 1100b จะสังเกตว่าบิตแรกถ้าเป็น 1 จะหมายถึงจำนวนลบเหมือนกับวิธีที่ 1 งั้นเราลองมาบวกกัน

0001b  (1)
     +
1100b  (-3)
1101b // 1+(-3) = -2 
-------------------------

0010b  (2)
     +
1100b  (-3)
1110b // 2+(-3) = -1
-------------------------

0011b   (3)
     +
1100b   (-3)
1111b // 3+(-3) = -0 

Enter fullscreen mode Exit fullscreen mode

เราสรุปได้ว่า
1101b = -2
1110b = -1
1111b = -0

ด้วยวิธีนี้ เราสามารถบวกลบเลขได้ปกติ เพียงแต่ว่ายังเหลือ 1 ปัญหาคือ ยังมี -0 อยู่(1111b)

วิธีที่ 3.

2's complement
วิธีที่ 2 เกือบดี เหลือปัญหาอีกข้อเดียว คือ -0 ซึ่งมันไม่ make sense ที่จะมี -0 ซึ่งทำให้เราเก็บค่าได้น้อยลง 1 ตัวด้วย
วิธีนี้แก้ไขได้ด้วยการเอา 1 มาบวกเข้าไปกับ 1's complement ดังนั้น -3 จะเป็น (1100+1) => 1101b
เราลองมาพิศูจน์กันว่า -0 จะหายไปรึป่าว

0001b   (1)
     +
1101b   (-3)
1110b // 1+(-3) = -2 
-------------------------

0010b   (2)
     +
1101b   (-3)
1111b // 2+(-3) = -1
-------------------------

0011b    (3)
     +
1101b    (-3)
0000b // Yes !! 3+(-3) = 0
Enter fullscreen mode Exit fullscreen mode

เราสรุปได้ว่า
1110b = -2
1111b = -1
0000b = 0

จะเห็นว่า 2's complement perfect สุด
ดังนั้นตัวแปรที่เป็นเลขบวกและลบ(Signed) จึงจะถูกเก็บในรูปแบบ 2'complement นั่นเอง

Top comments (0)