Representing Negative Numbers การแทนจำนวนติดลบ
Two's complement with a fixed bit width ทูส์คอมพลีเมนต์กับความกว้างบิตคงที่
A computer stores an integer in a fixed number of bits, so the sign (positive or negative) must be encoded inside those bits — there is no separate “minus sign”. Three schemes have been used for this: sign-and-magnitude, one's complement, and two's complement. Modern computers use two's complement, so this lesson focuses on it and shows every calculation step by step.
คอมพิวเตอร์เก็บจำนวนเต็มด้วยจำนวนบิตคงที่ จึงต้องเข้ารหัสเครื่องหมาย (บวกหรือลบ) ไว้ภายในบิตเหล่านั้น ไม่มี “เครื่องหมายลบ” แยกต่างหาก ระบบที่เคยใช้มี 3 แบบ คือ sign-and-magnitude, one's complement และ two's complement คอมพิวเตอร์สมัยใหม่ใช้ two's complement บทนี้จึงเน้นที่ระบบนี้ และแสดงการคำนวณทีละขั้น
Three ways to represent a negative number สามวิธีในการแทนจำนวนติดลบ
-
Sign-and-magnitude: the leftmost bit is the sign (
0positive,1negative); the remaining bits hold the plain magnitude. Sign-and-magnitude: บิตซ้ายสุดเป็นเครื่องหมาย (0บวก,1ลบ) บิตที่เหลือเก็บ “ขนาด” ตรง ๆ - One's complement: a negative value is the positive value with every bit inverted. One's complement: จำนวนลบคือจำนวนบวกที่กลับทุกบิต
- Two's complement: a negative value is the positive value inverted, then add 1. Ordinary binary addition then works for both signs. Two's complement: จำนวนลบคือจำนวนบวกที่กลับทุกบิตแล้วบวก 1 จากนั้นการบวกเลขฐานสองแบบปกติใช้ได้กับทั้งบวกและลบ
Example: how +5 and -5 look in 4 bits under each scheme.
ตัวอย่าง +5 และ -5 ในระบบ 4 บิต ของแต่ละแบบ
| Scheme ระบบ | +5 |
-5 |
Patterns for zero รูปแบบของศูนย์ | Note ข้อสังเกต |
|---|---|---|---|---|
| Sign-and-magnitude | 0101 |
1101 |
2 (0000, 1000)
2 แบบ (0000, 1000)
|
Addition/subtraction needs special handling. บวก/ลบต้องจัดการเป็นกรณีพิเศษ |
| One's complement | 0101 |
1010 |
2 (0000, 1111)
2 แบบ (0000, 1111)
|
Needs an end-around carry when adding. ต้องมี end-around carry เวลาบวก |
| Two's complement | 0101 |
1011 |
1 (0000)
1 แบบ (0000)
|
Normal binary addition works → the one we use. บวกเลขฐานสองแบบปกติได้ → แบบที่เราใช้ |
From here on, “negative number” means the two's complement pattern.
ต่อจากนี้ “จำนวนติดลบ” หมายถึงบิตแพทเทิร์นแบบ two's complement
The range for N bits ช่วงค่าเมื่อมี N บิต
- Lowest value: \(-2^{N-1}\) Highest value: \(2^{N-1}-1\). ค่าต่ำสุด: \(-2^{N-1}\) ค่าสูงสุด: \(2^{N-1}-1\)
- There are \(2^{N}\) patterns in total: half for \(0\) and the positives, half for the negatives. มีทั้งหมด \(2^{N}\) รูปแบบ: ครึ่งหนึ่งสำหรับ \(0\) และจำนวนบวก อีกครึ่งสำหรับจำนวนลบ
| Bits (N) จำนวนบิต (N) | Lowest \(-2^{N-1}\) ต่ำสุด \(-2^{N-1}\) | Highest \(2^{N-1}-1\) สูงสุด \(2^{N-1}-1\) | Total patterns \(2^{N}\) จำนวนรูปแบบ \(2^{N}\) |
|---|---|---|---|
| 4 | −8 | 7 | 16 |
| 8 | −128 | 127 | 256 |
Encoding: denary → two's complement pattern การเข้ารหัส: ฐานสิบ → บิตแพทเทิร์นทูส์คอมพลีเมนต์
Example: represent -45 in 8 bits. Each table row is one step.
ตัวอย่าง แทน -45 ในระบบ 8 บิต แต่ละแถวของตารางคือหนึ่งขั้น
Method A — invert, then add 1: start from +45, invert every bit, then add 1.
วิธี A — กลับบิตแล้วบวก 1: เริ่มจาก +45 กลับทุกบิต แล้วบวก 1
| Step ขั้น | Bits (8-bit) บิต (8 บิต) |
|---|---|
Start: +45
เริ่ม: +45
|
0010 1101 |
| Invert every bit กลับทุกบิต | 1101 0010 |
| Add 1 บวก 1 | 1101 0011 |
Method B — \(2^{N} - k\): subtract the magnitude \(k\) from \(2^{N}\), then write the result in \(N\) bits. วิธี B — \(2^{N} - k\): เอาขนาด \(k\) ลบออกจาก \(2^{N}\) แล้วเขียนผลลัพธ์เป็น \(N\) บิต
| Step ขั้น | Value ค่า |
|---|---|
| \(2^{8}\) | 256 |
| Subtract magnitude \(k = 45\) ลบขนาด \(k = 45\) | \(256 - 45 = 211\) |
| Write 211 in 8 bits เขียน 211 เป็น 8 บิต | 1101 0011 |
Both methods agree: -45 = 1101 0011.
ทั้งสองวิธีได้ผลตรงกัน: -45 = 1101 0011
Decoding: two's complement pattern → denary การถอดรหัส: บิตแพทเทิร์นทูส์คอมพลีเมนต์ → ฐานสิบ
Example: what value is 1101 0011 (8-bit two's complement)? Here are two methods that give the same answer.
ตัวอย่าง 1101 0011 (ทูส์คอมพลีเมนต์ 8 บิต) คือค่าใด? นี่คือสองวิธีที่ให้คำตอบเดียวกัน
Method 1 — negative-weight leftmost bit: like the place-value method, but the leftmost column is worth \(-2^{N-1}\) instead of \(+2^{N-1}\). Multiply each bit by its place value, then add. แบบที่ 1 — น้ำหนักหลักซ้ายสุดเป็นลบ: เหมือนวิธีค่าประจำหลัก แต่คอลัมน์ซ้ายสุดมีค่า \(-2^{N-1}\) แทน \(+2^{N-1}\) คูณบิตแต่ละตัวด้วยค่าประจำหลัก แล้วบวกกัน
| Place (N) หลัก (N) | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Total (base 10) รวม (เลขฐาน 10) |
|---|---|---|---|---|---|---|---|---|---|
| Bit บิต | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | – |
| Bit × place value บิต × ค่าประจำหลัก | \(1 \times (-2^{7})\) | \(1 \times 2^{6}\) | \(0 \times 2^{5}\) | \(1 \times 2^{4}\) | \(0 \times 2^{3}\) | \(0 \times 2^{2}\) | \(1 \times 2^{1}\) | \(1 \times 2^{0}\) | −45 |
| Numeric value ค่าตัวเลข | −128 | 64 | 0 | 16 | 0 | 0 | 2 | 1 | −45 |
Method 2 — invert, add 1, then negate: the sign bit is 1, so the value is negative. Invert every bit and add 1 to get the magnitude, then put the minus sign back.
แบบที่ 2 — กลับบิต บวก 1 แล้วใส่เครื่องหมายลบ: บิตเครื่องหมายเป็น 1 จึงเป็นจำนวนลบ กลับทุกบิตแล้วบวก 1 เพื่อหาขนาด จากนั้นใส่เครื่องหมายลบกลับ
| Step ขั้น | Bits / value บิต / ค่า |
|---|---|
Sign bit is 1 → negative
บิตเครื่องหมายเป็น 1 → จำนวนลบ
|
1101 0011 |
| Invert every bit กลับทุกบิต | 0010 1100 |
| Add 1 → magnitude บวก 1 → ขนาด | 0010 1101 = 45 |
| Put the minus sign back ใส่เครื่องหมายลบกลับ | −45 |
Both methods give −45. ทั้งสองวิธีได้ −45 เท่ากัน
Quick sign check ตรวจเครื่องหมายอย่างเร็ว
If you only need the sign, read the leftmost bit: 0 means the value is
\(0\) or positive, 1 means it is negative. For example 0011 0110 is
non-negative, and 1101 0011 is negative. You only do the full decode when you
need the actual number.
ถ้าต้องการแค่เครื่องหมาย ให้อ่านบิตซ้ายสุด: 0 คือค่าเป็น \(0\) หรือบวก,
1 คือค่าติดลบ เช่น 0011 0110 ไม่ติดลบ ส่วน 1101 0011 ติดลบ
จะถอดค่าเต็มก็ต่อเมื่อต้องการตัวเลขจริง ๆ
Check your work with Python ตรวจคำตอบด้วย Python
The by-hand methods above are the point of this lesson. These optional demos just confirm the same
answers. 2 ** n is “2 to the power n”, and for an 8-bit value
255 - x flips every bit (it is 11111111 minus x).
วิธีทำด้วยมือด้านบนคือหัวใจของบทนี้ ตัวอย่างด้านล่างเป็นทางเลือกไว้ยืนยันคำตอบเดียวกัน
2 ** n คือ “2 ยกกำลัง n” และสำหรับค่า 8 บิต 255 - x
คือการกลับทุกบิต (เท่ากับ 11111111 ลบด้วย x)
1 Range for N = 4 and N = 8
1 ช่วงค่าเมื่อ N = 4 และ N = 8
Lowest is -(2 ** (N - 1)) and highest is (2 ** (N - 1)) - 1.
This matches the range table: -8 to 7 for 4 bits, -128 to 127 for 8 bits.
ค่าต่ำสุดคือ -(2 ** (N - 1)) และสูงสุดคือ (2 ** (N - 1)) - 1
ตรงกับตารางช่วงค่า: -8 ถึง 7 สำหรับ 4 บิต และ -128 ถึง 127 สำหรับ 8 บิต
-8 7 -128 127
2 Encode -45 in 8 bits (both methods)
2 เข้ารหัส -45 ในระบบ 8 บิต (สองวิธี)
Method B is (2 ** 8) - 45. Method A inverts the 8 bits of +45
(int("00101101", 2) reads the bit string as base 2) with 255 - pos, then adds 1.
bin() shows the pattern with a 0b prefix.
วิธี B คือ (2 ** 8) - 45 ส่วนวิธี A กลับ 8 บิตของ +45
(int("00101101", 2) อ่านสตริงบิตเป็นฐานสอง) ด้วย 255 - pos แล้วบวก 1
bin() แสดงแพทเทิร์นโดยขึ้นต้นด้วย 0b
211 211 0b11010011
3 Decode 11010011 — negative-weight leftmost bit
3 ถอดรหัส 11010011 — น้ำหนักหลักซ้ายสุดเป็นลบ
bits[0] is the first character and bits[1:] is the rest of the string.
The leftmost bit is worth -128 (\(-2^{7}\)); the other 7 bits keep their normal
place values, so int(bits[1:], 2) adds them up.
bits[0] คือตัวอักษรตัวแรก และ bits[1:] คือส่วนที่เหลือของสตริง
บิตซ้ายสุดมีค่า -128 (\(-2^{7}\)) ส่วนอีก 7 บิตใช้ค่าประจำหลักปกติ
ดังนั้น int(bits[1:], 2) จึงบวกรวมให้
-128 83 -45
4 Decode 11010011 — invert, add 1, negate
4 ถอดรหัส 11010011 — กลับบิต บวก 1 ใส่ลบ
The sign bit is 1, so invert the 8 bits with 255 - pattern, add 1
to get the magnitude, then negate it with -magnitude.
บิตเครื่องหมายเป็น 1 จึงกลับ 8 บิตด้วย 255 - pattern แล้วบวก 1
เพื่อหาขนาด จากนั้นใส่เครื่องหมายลบด้วย -magnitude
45 -45
5 Compare the three schemes for -5 (4-bit)
5 เทียบสามระบบสำหรับ -5 (4 บิต)
Sign-and-magnitude joins the sign bit "1" to the magnitude "101" with
+ (string join). One's complement is 15 - 5 (invert 4 bits);
two's complement is 16 - 5 (\(2^{4} - k\)).
Sign-and-magnitude นำบิตเครื่องหมาย "1" มาต่อกับขนาด "101" ด้วย + (ต่อสตริง)
One's complement คือ 15 - 5 (กลับ 4 บิต) ส่วน two's complement คือ 16 - 5 (\(2^{4} - k\))
1101 0b1010 0b1011
Note: Run uses a JavaScript simulator, not real Python. For real Python, try Google Colab. หมายเหตุ: ปุ่ม Run จำลองด้วย JavaScript ไม่ใช่ Python จริง หากต้องการ Python จริง ลองใช้ Google Colab
References References / แหล่งอ้างอิง
Sources used for representing negative numbers:
แหล่งที่ใช้ประกอบเนื้อหาการแทนจำนวนติดลบ:
- Signed number representations — Wikipedia — Signed number representations (sign-and-magnitude, one's complement, two's complement comparison) (เทียบ sign-and-magnitude, one's complement และ two's complement)
- Two's complement — Wikipedia — Two's complement (sign bit, range, negative-weight MSB, and the invert-and-add-1 method) (บิตเครื่องหมาย ช่วงค่า น้ำหนัก MSB เป็นลบ และวิธีกลับบิตแล้วบวก 1)
-
Python
bin/int— Built-in Functions — bin / int (used in the check-your-work demos) (ใช้ในตัวอย่าง Run สำหรับตรวจคำตอบ)