Notes & software courses · Free to learn
Aph's Blog
On this page

เลขฐานสอง & การเก็บข้อมูล

👋 อ่านฟรีทั้งหมดบน Aph's Blog — เนื้อหาภาษาไทย ทำตามทีละหน้าใน sidebar ได้เลย หากมีข้อเสนอแนะหรืออยากให้เพิ่มหัวข้อไหน บอกได้เสมอ

ทำไมทุกอย่าง — ตัวเลข ตัวอักษร รูป เสียง — ล้วนเป็น 0 กับ 1 และคอมพิวเตอร์เก็บมันอย่างไร

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

ทุกอย่างคือ 0 กับ 1 (Binary)

ภายในคอมพิวเตอร์มีวงจรไฟฟ้านับล้าน แต่ละจุดมีแค่ 2 สถานะ: มีไฟ (1) กับ ไม่มีไฟ (0) สถานะเดียวนี้เรียกว่า 1 bit ทุกอย่าง — ตัวเลข ตัวอักษร รูปภาพ เสียง วิดีโอ — ถูกแปลงเป็นชุดของ 0 กับ 1 ทั้งหมด

หน่วยขนาดเก็บได้ประมาณ
1 bitเลข 0 หรือ 1 หนึ่งตัว2 ค่า
1 byte8 bits256 ค่า (เช่น 1 ตัวอักษร)
1 KB (กิโลไบต์)1,024 bytesข้อความสั้น ๆ
1 MB (เมกะไบต์)1,024 KBรูปภาพ 1 รูป
1 GB (กิกะไบต์)1,024 MBหนังสั้น ๆ
1 TB (เทระไบต์)1,024 GBหนัง/รูปเป็นพัน ๆ

นับเลขฐานสองอย่างไร

ระบบเลขฐานสองทำงานเหมือนฐานสิบที่เราใช้ทุกวัน แต่ใช้แค่ 0–1 แทน 0–9 ในฐานสิบแต่ละหลักคือ 1, 10, 100... ส่วนฐานสองแต่ละหลักคือ 1, 2, 4, 8, 16...

เลขฐานสอง 1101 แปลงเป็นฐานสิบ:

  1      1      0      1
  ×8     ×4     ×2     ×1
  = 8  + 4  +  0  +  1   = 13

หลักของฐานสอง (จากขวา): 1, 2, 4, 8, 16, 32, ...
python
# ลองให้ Python แปลงให้ดู
print(bin(13))         # 0b1101  (0b = นี่คือเลขฐานสอง)
print(int('1101', 2))  # 13      (แปลงฐานสองกลับเป็นฐานสิบ)

# ฐานสิบหก (hex) ก็เจอบ่อย เช่นใช้ระบุสี #FF0000 = แดง
print(hex(255))        # 0xff
ทำไมต้องใช้ฐานสองและฐานสิบหก

ฐานสองคือภาษาแท้ของฮาร์ดแวร์ ส่วนฐานสิบหก (hex, 0-9 และ A-F) เป็นวิธีเขียนเลขฐานสองให้สั้นลง (4 bits = 1 หลัก hex) จึงเจอบ่อยในเรื่องสี (#FF0000), ที่อยู่หน่วยความจำ และ encoding

ตัวอักษรถูกเก็บอย่างไร

ในเมื่อคอมพิวเตอร์รู้จักแค่ตัวเลข แล้วเก็บตัวอักษรได้อย่างไร? คำตอบคือมี "ตาราง" กำหนดว่าตัวอักษรแต่ละตัวแทนด้วยเลขอะไร มาตรฐานพื้นฐานคือ ASCII (ตัวอักษรอังกฤษ) และมาตรฐานสมัยใหม่ที่รองรับทุกภาษา (รวมไทยและ emoji) คือ Unicode

python
# ตัวอักษรแต่ละตัวมีเลขประจำตัว
print(ord('A'))   # 65   (A = 65 ในตาราง ASCII)
print(ord('a'))   # 97   (a ตัวเล็ก = 97 คนละค่ากับ A!)
print(chr(66))    # B    (เลข 66 = ตัวอักษร B)
print(ord('ก'))   # 3585 (ภาษาไทยใช้ Unicode)

# ข้อความคือลำดับของตัวอักษรหลายตัวต่อกัน
word = "Hi"        # ภายในเก็บเป็น [72, 105]
ทำไมต้องรู้เรื่องนี้

เมื่อเข้าใจว่าทุกอย่างเป็นตัวเลข คุณจะเข้าใจบั๊กที่เจอบ่อย เช่นภาษาไทยกลายเป็นตัวประหลาด (encoding ผิด — อ่านด้วยตารางคนละตัว) หรือทำไม 'A' ไม่เท่ากับ 'a' (เพราะ 65 ≠ 97)

รูปภาพ เสียง วิดีโอ ก็เป็นตัวเลข

  • รูปภาพ — แบ่งเป็นจุดเล็ก ๆ (pixel) แต่ละจุดเก็บค่าสี RGB เป็นตัวเลข (เช่นแดง=255, เขียว=0, น้ำเงิน=0)
  • เสียง — วัดความดังเป็นตัวเลขหลายพันครั้งต่อวินาที
  • วิดีโอ — คือรูปภาพหลายเฟรมต่อกัน + เสียง

นี่คือเหตุผลที่ไฟล์รูป/วิดีโอมีขนาดใหญ่ และทำไมการ "บีบอัด" (compression เช่น JPG, MP4) จึงสำคัญ — มันลดจำนวนตัวเลขที่ต้องเก็บลง

ขีดจำกัดของตัวเลข & ทศนิยมที่ไม่เป๊ะ (สำคัญมากในงานจริง)

เพราะตัวเลขถูกเก็บด้วย bit จำนวนจำกัด ในหลายภาษา (เช่น C, Java, JavaScript) ตัวเลขจึงมี "ค่าสูงสุด" ถ้าเกินจะเกิด integer overflow (ค่าวนกลับเป็นติดลบหรือเพี้ยน) — โชคดีที่ Python จัดการเลขจำนวนเต็มขนาดใหญ่ให้อัตโนมัติ แต่ภาษาอื่นต้องระวัง

ส่วนเลขทศนิยม (float) เก็บแบบประมาณค่า ทำให้บางครั้งไม่เป๊ะ — นี่คือบั๊กคลาสสิกที่ทุกภาษาเป็นเหมือนกัน:

python
print(0.1 + 0.2)            # 0.30000000000000004  (ไม่ใช่ 0.3 เป๊ะ!)
print(0.1 + 0.2 == 0.3)     # False  (กับดักที่มือใหม่งงมาก)

# วิธีเทียบ float ที่ถูกต้อง: ดูว่าใกล้กันพอไหม
print(abs((0.1 + 0.2) - 0.3) < 1e-9)   # True

# งานเงินจริง ๆ เลี่ยง float — ใช้จำนวนเต็มหน่วยสตางค์ หรือ Decimal
from decimal import Decimal
print(Decimal("0.1") + Decimal("0.2"))  # 0.3  (เป๊ะ)
ทำไมต้องรู้

อย่าเทียบ float ด้วย == ตรง ๆ และอย่าใช้ float กับเงิน — นี่คือบั๊กที่ทำให้ระบบคำนวณเงินผิดได้จริง การเข้าใจว่า "ทศนิยมเก็บแบบประมาณ" มาจากเรื่อง bit ช่วยให้คุณหลบกับดักนี้ได้ตั้งแต่ต้น

สรุปหัวข้อนี้

  • ภายในคอมพิวเตอร์มีแค่ 2 สถานะ: 0 กับ 1 (1 bit), 8 bits = 1 byte
  • เลขฐานสองนับด้วยหลัก 1, 2, 4, 8, 16... — bin()/int(x,2) ช่วยแปลง
  • ตัวอักษรเก็บด้วยตารางตัวเลข: ASCII (อังกฤษ), Unicode (ทุกภาษา + emoji)
  • รูป/เสียง/วิดีโอ ก็ถูกแปลงเป็นตัวเลขทั้งหมด จึงต้องมีการบีบอัด
แบบฝึกหัด

1) แปลงเลข 25 เป็นฐานสองด้วยมือ แล้วเช็คด้วย bin(25) 2) ใช้ ord() หาเลขประจำตัวของตัวอักษรตัวแรกในชื่อคุณ 3) เลข 0b1010 มีค่าเท่าไหร่ในฐานสิบ? 4) ลอง chr() กับเลข 65 ถึง 90 ดูว่าได้ตัวอักษรอะไรบ้าง