CodeQuiz EP.28 - ทำไม bool(67)=True

พี่กัปตัน กนกลักษณ์

เผยแพร่เมื่อ

อัปเดตล่าสุดเมื่อ

CodeQuiz EP.28 - ทำไม bool(67)=True

สาระสำคัญ

  • จุดเริ่มต้นของ Boolean
  • ทำไมค่า "ไม่ใช่ศูนย์" ถึงถูกตีความว่าจริง ?
  • การกำหนดให้ True = 1 เป็นมาตรฐาน

TL;DR

Boolean มีรากฐานจาก Boolean Algebra ของ George Boole ในศตวรรษที่ 19 เมื่อคอมพิวเตอร์ถูกพัฒนาขึ้น 0 (ไม่มีสัญญาณ) ถูกแมปเป็น False และ 1 (มีสัญญาณ) เป็น True แต่ในระดับฮาร์ดแวร์ ระบบแค่ถามว่า "ค่านี้เป็นศูนย์หรือไม่?" ถ้าไม่ใช่ศูนย์ ไม่ว่าจะเป็น 2, -5 หรือ 100 ก็ถือว่า True ทั้งหมด เพราะการเช็คว่าเป็นศูนย์หรือไม่นั้นเร็วกว่าการเทียบว่าเท่ากับ 1 พอดี ส่วนที่ True ถูกกำหนดให้เท่ากับ 1 เสมอนั้น เป็นเพราะต้องมี "ตัวแทนมาตรฐาน" เพื่อให้การคำนวณสม่ำเสมอ เช่น True + True = 2 ได้พอดี

จุดเริ่มต้นของ Boolean

หากใครเคยเขียนโค้ดมาบ้าง น่าจะคุ้นเคยกับคำว่า Boolean ที่มีค่าเพียงสองค่า คือ True และ False ใช่มั้ยคะ แต่เคยสงสัยไหมว่า ทำไมในภาษาโปรแกรมหลายภาษา เมื่อเราเขียน if 2: หรือ if -5: โค้ดกลับทำงานได้ และถูกตีความว่าเป็น True ทั้งหมด?

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

EP.28 ทำไม bool(67)=True - 03.png

Boolean ที่เราใช้กันอยู่ในปัจจุบันไม่ได้เกิดจากคนเขียนโปรแกรมตั้งกฎขึ้นมาเอง แต่มันมีรากฐานมาจาก Boolean Algebra ซึ่งเป็นระบบตรรกะทางคณิตศาสตร์ที่ถูกพัฒนาขึ้นโดย George Boole ในศตวรรษที่ 19 ระบบตรรกะนี้มีหลักการง่าย ๆ คือ มีเพียงสองสถานะเท่านั้น ได้แก่ จริง (True) และ เท็จ (False) ซึ่งใช้ในการวิเคราะห์ตรรกะและการให้เหตุผล


เมื่อคอมพิวเตอร์เริ่มถูกพัฒนาขึ้นมา นักออกแบบระบบต้องหาวิธีแปลงแนวคิดทางตรรกะนี้ให้อยู่ในรูปแบบที่เครื่องจักรสามารถเข้าใจได้ ซึ่งคอมพิวเตอร์ในยุคแรกๆ ทำงานด้วยระบบไฟฟ้าและบิต (bit) ที่มีค่าได้เพียง 0 และ 1

การแมปที่เป็นธรรมชาติที่สุดจึงเกิดขึ้น นั่นคือ 0 แทนสถานะ "ไม่มีสัญญาณไฟฟ้า" ซึ่งหมายถึง False และ 1 แทนสถานะ "มีสัญญาณไฟฟ้า" ซึ่งหมายถึง True การแมปนี้ดูจะตรงไปตรงมาและสมเหตุสมผล แต่ในความเป็นจริงของฮาร์ดแวร์ เรื่องมันไม่ได้ง่ายขนาดนั้น เพราะ "มีสัญญาณ" ไม่ได้หมายถึงแค่ค่า 1 เท่านั้น แต่รวมถึงค่าอื่น ๆ ที่ไม่ใช่ศูนย์ทั้งหมด ซึ่งนี่คือจุดเริ่มต้นของความซับซ้อนที่น่าสนใจ

EP.28 ทำไม bool(67)=True - 05.png

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

เมื่อเราลงลึกไปในระดับฮาร์ดแวร์และภาษาโปรแกรมระดับต่ำ เช่น C หรือ Assembly เราจะพบว่าการตรวจสอบเงื่อนไข (condition checking) นั้นถูกออกแบบให้ทำงานอย่างง่ายและรวดเร็วที่สุด คำถามพื้นฐานที่ระบบถามตัวเองคือ "ค่าในหน่วยความจำหรือในเรจิสเตอร์นี้เป็นศูนย์หรือไม่?" ถ้าคำตอบคือใช่ ระบบจะตีความว่าเงื่อนไขล้มเหลว (False) แต่ถ้าคำตอบคือไม่ใช่ ไม่ว่าค่านั้นจะเป็น 1, 2, -1, 100, หรือแม้แต่ -999 ระบบก็จะตีความว่าเงื่อนไขผ่าน (True)แนวคิดนี้ไม่ได้เกิดขึ้นมาโดยบังเอิญ แต่มันมีเหตุผลที่ชัดเจนทั้งในด้านประสิทธิภาพและความยืดหยุ่น ในระดับฮาร์ดแวร์ การเปรียบเทียบว่าค่าหนึ่งเป็นศูนย์หรือไม่นั้นทำได้รวดเร็วมาก เพราะมันเป็นเพียงการตรวจสอบบิตทั้งหมดว่าเป็น 0 หรือไม่ ซึ่งง่ายกว่าการเปรียบเทียบว่าค่านั้นเท่ากับ 1 เป๊ะ ๆ หรือไม่ นอกจากนี้ ความยืดหยุ่นในการยอมรับค่าที่ไม่ใช่ศูนย์ทั้งหมดเป็น True ยังทำให้โปรแกรมเมอร์สามารถเขียนโค้ดได้สะดวกขึ้น เช่น สามารถนับจำนวนแล้วใช้จำนวนนั้นเป็นเงื่อนไขได้ทันที โดยไม่ต้องเปรียบเทียบกับศูนย์อย่างชัดเจน นี่คือเหตุผลว่าทำไมในภาษาโปรแกรมหลายภาษา การเขียนโค้ดแบบ if 2: หรือ if -5: จึงทำงานได้และถูกตีความว่าเป็น True ทั้งหมด

EP.28 ทำไม bool(67)=True - 07.png

การเลือกใช้ 1 เป็นตัวแทนของ True นั้นมีเหตุผลหลายประการ

  1. มันสอดคล้องกับระบบเลขฐานสอง (binary system) ที่คอมพิวเตอร์ใช้งานอยู่แล้ว โดยที่ 0 และ 1 เป็นหน่วยพื้นฐานที่สุดของข้อมูล
  2. มันทำให้ Boolean สามารถใช้งานร่วมกับการคำนวณทางคณิตศาสตร์ได้อย่างราบรื่น ตัวอย่างเช่น ใน Python เมื่อคุณเขียน `True + True` คุณจะได้ค่า 2 หรือเมื่อเขียน `False + True` จะได้ค่า 1 การที่ True และ False สามารถเข้าร่วมการคำนวณได้นี้ทำให้เกิดเทคนิคการเขียนโค้ดหลายรูปแบบ เช่น การนับจำนวนเงื่อนไขที่เป็นจริง (count of true conditions) ได้โดยการบวกกันตรงๆ
  3. การมีค่ามาตรฐานช่วยลดความสับสนในการเปรียบเทียบและการแสดงผล เมื่อคุณต้องการแปลง Boolean กลับเป็นตัวเลข หรือแสดงผลออกมาเป็นข้อความ การมีค่ามาตรฐานที่ตายตัวจะทำให้ผลลัพธ์สม่ำเสมอและคาดเดาได้ นี่คือเหตุผลว่าทำไมแม้คุณจะส่งค่า 5 เข้าไปในเงื่อนไข และมันถูกตีความว่า True แต่เมื่อคุณแปลง True กลับมาเป็นตัวเลข คุณจะได้ 1 เสมอ ไม่ใช่ 5