Numbers in depth
ในบทนี้ เราจะมาเรียนรู้เกี่ยวกับเรื่องตัวเลขให้ละเอียดขึ้นกันนิดนึงดีกว่าครับ
🧐 Deep dive
ในส่วนนี้จะเป็นความรู้เชิงลึกครับ ไม่ต้องเข้าใจทั้งหมดก็ได้
ในภาษา javascript เราสามารถเขียนตัวเลขได้หลายวิธีครับ อันนี้คือเบสิคสุด คือจำนวนเต็มธรรมดาครับ
123123จำนวนทศนิยม ก็เขียนได้ โดยใส่เครื่องหมาย . เข้าไปครับ
3.143.14ถ้าใส่เครื่องหมายลบข้างหน้า ก็จะได้เป็นตัวเลขติดลบครับ
-128-128เราสามารถเอาตัวเลขมาบวก ลบ คูณ หารกันได้
25 * 25625หรือถ้าเราเอา
0.1มาบวกกับ0.2เราก็จะได้…0.1 + 0.20.30000000000000004…อ้าว ทำไมเป็นแบบนี้ล่ะ? ทำไม 0.1 + 0.2 ไม่ได้ 0.3 ล่ะ คอมพิวเตอร์คำนวณผิดหรือเปล่า หรือมันมั่วหรือเปล่า?
- อย่างที่เคยเกริ่นไว้ในบทแรกครับ แทบทุกอย่างที่คอมพิวเตอร์ทำ มีเหตุผลอธิบายได้เสมอ
คือมาตรฐานของภาษา JavaScript ได้ระบุไว้ว่า ตัวเลขต่างๆ จะเก็บไว้ในหน่วยความจำ ในรูปแบบที่เรียกกันว่า “double-precision floating-point”
พูดง่ายๆ ก็คือ มนุษย์ กับ คอมพิวเตอร์ ประมวลผลตัวเลข คนละวิธีกันครับ
เวลาผมเขียนตัวเลข 0.1 กับ 0.2 คอมพิวเตอร์จะเก็บมันในหน่วยความจำ แต่ในรูปของเลข 0 กับ 1 จำนวน 64 ตัว

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

ทีนี้ พอเอามาบวกกันก็จะได้ตัวเลขนี้ครับ แต่ตอนที่เอามาแสดงผล มันถูกตัดตอนตรงหลังเลข 4 พอดี จึงเห็นเป็น 0.30000000000000004

ตรงส่วนนี้ ถ้าไม่เข้าใจก็ไม่เป็นไรนะครับ แค่จะโชว์ให้ดูว่า มันมีเหตุผลของมัน[1]
และเหตุผลเดียวกันนี้เอง ทำให้เวลาเราเก็บข้อมูลตัวเลขที่เยอะมากๆ ใน JavaScript บางทีจะเกิดการปัดขึ้น หรือปัดลง ไปยังตัวเลขที่ใกล้เคียงครับ[2]

เกร็ดความรู้เพิ่มเติมเกี่ยวกับตัวเลข
ต่อไปนี้ คือเกร็ดความรู้เพิ่มเติมเกี่ยวกับตัวเลขครับ เกร็ดความรู้พวกนี้ ถ้าไม่รู้ ก็ไม่ได้ทำให้เขียนโค้ดไม่ได้ครับ แต่เวลาเราอ่านโค้ดของคนอื่น บางทีก็จะเจอของพวกนี้ครับ เลยอยากให้รู้ว่ามันมีของพวกนี้อยู่ด้วย
เวลาตัวเลขมีจำนวนหลักมากๆ แล้วถ้ามันอ่านยาก เราสามารถใส่เครื่องหมาย
_คั่นไว้ เพื่อให้อ่านง่ายขึ้นได้ครับ1_000_0001000000แต่ห้ามใส่เครื่องหมายเว้นวรรค ก่อนหรือหลังตัว underscore
1 _ 000 _ 000Uncaught SyntaxError: Unexpected identifier '_'>ตัวเลขจำนวนเต็มที่ขึ้นต้นด้วย
0จะถือว่าเป็นตัวเลขที่เขียนในรูปของเลขฐานแปด (octal)03125จำนวนเต็มที่ขึ้นต้นด้วย
0bจะถือว่าเป็นตัวเลขที่เขียนในรูปของเลขฐานสอง (binary)0b0110000197และจำนวนเต็มที่ขึ้นต้นด้วย
0xจะถือว่าเป็นตัวเลขที่เขียนในรูปของเลขฐานสิบหก (hexadecimal)0x6197เราสามารถใส่ตัว
eเพื่อเขียนตัวเลขในรูปแบบของสัญลักษณ์วิทยาศาสตร์ได้1.2e612000001e-20.01โดยห้ามมีช่องว่างระหว่าง
eกับตัวเลขครับ1e - 2Uncaught SyntaxError: Invalid or unexpected token>
ถ้าอยากเข้าใจแบบละเอียดมากขึ้น ก็ไปอ่านบทความเรื่อง What Every Computer Scientist Should Know About Floating-Point Arithmetic (ยาว 74 หน้า) ดูได้ครับ ผมเองก็ยังอ่านบทความนี้ไม่ค่อยรู้เรื่องเหมือนกัน ลึกเกิน ↩︎
หากต้องการที่จะเก็บข้อมูลตัวเลขที่มีค่าเยอะขนาดนั้น (ตัวเลขที่มากกว่า 9,007,199,254,740,991) อย่างแม่นยำจริงๆ ภาษา JavaScript มีชนิดข้อมูล BigInt ให้ใช้ แต่จะไม่ได้สอนในคอร์สนี้ครับ ↩︎