ผมได้สัมผัสกับคอมพิวเตอร์ครั้งแรกก็ตอนเรียนแลปฟิสิกส์ปี
๑ เมื่อปี ๒๕๒๗ เป็นเครื่องไมโครคอมพิวเตอร์
8
บิท
ได้เรียนภาษา BASIC
แบบไม่รู้เรื่องรู้ราวอะไรเลย
(อันที่จริงยังไม่รู้ด้วยซ้ำว่าคอมพิวเตอร์คืออะไร)
จากนั้นในเทอมปลายจึงได้เรียนเขียนภาษา
FORTRAN
ตัวที่เรียกว่า
WATFIVที่เป็นตัวที่มหาวิทยาลัย
Waterloo
พัฒนาขึ้นมา
ตัวนี้เป็นตัวก้ำกึ่งระหว่าง
FORTRAN
IV (ตัวนี้มาก่อน
FORTRAN
66 อีก)
และ
FORTRAN
77 (มาตรฐานปีค.ศ.
๑๙๗๗)
ปีนั้นเรียกว่าโชคดีกว่ารุ่นพี่ตรงที่
เป็นปีแรกที่สามารถพิมพ์โปรแกรมผ่านทางเทอร์มินอลได้แล้ว
ไม่ต้องใช้บัตรเจาะรู
(บัตรกระดาษแข็ง
๑ บัตรต่อ ๑ บรรทัด
ที่ต้องเจาะรูแล้วไปให้เครื่องอ่านบัตรอ่านอีกที)
พอถึงปี
๔ ก่อนจบต้องเรียนวิชา Plant
Design (ออกแบบโรงงานนะ
ไม่ใช่ออกแบบพืช)
กัน
ตอนนั้นมี IBM
PC มาให้ใช้งานกันแล้ว
แต่ยังต้องนั่งเขียนโปรแกรมภาษา
BASIC
เพื่อทำการคำนวณทุกอย่าง
(ไม่มีซอร์ฟแวร์สำเร็จรูปให้ใช้เหมือนทุกวันนี้)
ระหว่างการคำนวณก็ได้เห็นพฤติกรรมแปลก
ๆ ของผลการคำนวณ เช่นถ้าให้คำนวณ
n
= n + 1 โดยให้
n
เริ่มต้นจาก
0
ก็พบว่าพอคำนวณไปได้สักพักคำตอบที่ได้มันกลับไม่ได้เป็นเลขจำนวนเต็ม
มันดันมีจุดทศนิยมโผล่ออกมา
แต่ตอนนั้นก็ไม่รู้ว่ามันเกิดจากอะไร
และไม่รู้ด้วยว่าจะไปหาคำอธิบายจากใครได้
ตอนเรียนเขียน
FORTRAN
นั้นก็เรียนรู้กันว่า
สำหรับบางคำสั่ง (เช่นคำสั่งนับการวน
loop)
ต้องมีการกำหนดค่าตัวแปรให้เป็นชนิด
"จำนวนเต็ม"
หรือ
"Integer"
ห้ามกำหนดเป็น
"จำนวนจริง"
หรือ
"Real"
ซึ่งก็ไม่รู้เหมือนกันว่าทำไมต้องทำอย่างนั้น
และยังไม่รู้ด้วยว่าคำสั่ง
"Double
precision" นั้นมีเอาไว้ทำไม
ข้อสงสัยต่าง
ๆ สมัยเรียนนั้นคงจะลืมไปหมด
ถ้าไม่ใช่เป็นเพราะตอนไปเรียนโทที่ต่างประเทศได้ทำงานวิจัยที่ต้องเขียนภาษา
FORTRAN
แล้วอาจารย์ที่ปรึกษาแนะนำให้ไปลงเรียนวิชาพื้นฐานการคำนวณเชิงตัวเลข
(การแก้โจทย์สมการคณิตศาสตร์ด้วยวิธีการคำนวณเชิงตัวเลข)
ตอนนั้นเองถึงได้เข้าใจว่าบนคอมพิวเตอร์นั้น
"จำนวนเต็ม"
ต่างกับ
"จำนวนจริง"
อย่างไร
และมันเกิดอะไรขึ้นเมื่อเราเอาเลขฐาน
10
(ซึ่งเป็นตัวเลขที่เราใช้กันในชีวิตประจำวัน)
ไปให้คอมพิวเตอร์คำนวณด้วยระบบเลขฐาน
2
ที่มันเข้าใจ
เนื้อหาในบทความชุดนี้เป็นการนำเอาสิ่งที่เขียนไว้สำหรับสอนนิสิตวิศวกรรมเคมีปี
๓ ในเรื่องพื้นฐานการคำนวณเชิงตัวเลขใน
"บทที่
๑ การคำนวณในระบบเลขทศนิยม"
ซึ่งอันที่จริงก็มีไฟล์
pdf
ไว้ให้ดาวน์โหลดฟรีบนหน้า
blog
อยู่แล้ว
เพียงแต่รูปแบบไฟล์ pdf
คงทำให้การค้นหาโดยใช้คำสำคัญค้นหาด้วย
google
นั้นทำให้มันหาไม่เจอ
ก็เลยนำมาเขียนเป็น text
ไว้บนหน้า
blog
หน่อย
เพราะช่วงสัปดาห์ที่ผ่านมาเห็นมีการกดแชร์บางบทความกัน
เลยทำให้รู้ว่าเรื่อง
"ความรู้พื้นฐาน"
นี้ยังมีคนไม่รู้อยู่มาก
แม้ว่าจะเป็นงานในสายวิชาชีพตัวเอง
โดยในบทความชุดนี้จะขอเริ่มจากคำถามง่าย
ๆ ข้างล่างก่อน
คำถาม
ถ้าต้องการคำนวณค่า (1
+ 1) บนคอมพิวเตอร์
โดยคำนวณในรูปแบบ
ก)
จำนวนเต็ม
ค่าของตัวเลขแต่ละตัวจะถูกบันทึกไว้ในรูปแบบ
1
ดังนั้นค่าที่ได้จากการคำนวณ
(1
+ 1) = ...............
ข)
จำนวนจริง
ค่าของตัวเลขแต่ละตัวจะถูกบันทึกไว้ในรูปแบบ
0.1 x 10
ดังนั้นค่าที่ได้จากการคำนวณ
(0.1 x 10 + 0.1 x 10) = ..............
เมื่อทำการคำนวณ
ผลลัพธ์ที่ได้จะออกมาเหมือนกันหรือไม่
ในชีวิตประจำวันของเรานั้นเราใช้เลขฐาน
10
(decimal digit) เป็นหลักในการติดต่อสื่อสารและการคำนวณต่าง
ๆ ตัวเลขฐาน 10
ที่ใช้มีตั้งแต่
0
ถึง
9
ค่าของเลขฐาน
10
แต่ละจำนวนขึ้นอยู่กับค่าประจำหลักดังแสดงในตารางที่
๑
ตารางที่
๑ ค่าประจำหลักของเลขฐาน
10
หลักที่
|
5
|
4
|
3
|
2
|
1
|
จุดทศนิยม
|
1
|
2
|
3
|
4
|
5
|
ค่าประจำหลัก
|
104
|
103
|
102
|
101
|
100
|
.
|
10-1
|
10-2
|
10-3
|
10-4
|
10-5
|
ระบบเลขฐาน
2
(binary digit)
เป็นระบบการคำนวณที่ใช้กันในเครื่องคอมพิวเตอร์แบบดิจิตอล
(digital
computer) ทั่วไป
เลขที่ใช้จะมีเพียงแค่ 0
กับ
1
ค่าของเลขฐาน
2
แต่ละจำนวนขึ้นอยู่กับค่าประจำหลักดังแสดงในตารางที่
๒ ข้างล่าง
ตารางที่
๒ ค่าประจำหลักของเลขฐาน
2
หลักที่
|
5
|
4
|
3
|
2
|
1
|
จุดทศนิยม
|
1
|
2
|
3
|
4
|
5
|
ค่าประจำหลัก
|
24
|
23
|
22
|
21
|
20
|
.
|
2-1
|
2-2
|
2-3
|
2-4
|
2-5
|
ในการแปลงเลขฐานสิบให้เป็นเลขฐานสอง
เราทำได้โดยการนำตัวเลขที่อยู่ในแต่ละหลักคูณเข้ากับค่าประจำหลัก
แล้วทำการบวกเข้าด้วยกัน
ดังเช่นในกรณีของเลขฐานสิบที่เป็นจำนวนเต็มในตารางที่
๓
ตารางที่
๓ ตัวอย่างตัวเลขฐาน 10
ที่เป็นจำนวนเต็มและตัวเลขฐาน
2
ที่เทียบเท่ากัน
-
เลขฐาน 10เลขฐานสอง18100101001100100100001001110001000015243110010110110110111110000000100110001001011010000011
จากตัวอย่างตัวเลขในตารางที่
๓ เราจะพบว่าสำหรับเลขฐานสิบที่เป็นเป็นเลขจำนวนเต็มแล้ว
เราสามารถเขียนเลขฐานสองที่มีค่าเท่ากับตัวเลขฐานสิบได้ทุกจำนวน
ต่อไปขอให้พิจารณากรณีการเปลี่ยนเลขฐานสิบที่เป็นเลขทศนิยมให้เป็นเลขฐานสองดังแสดงในตารางที่
๔
ตารางที่
๔ ตัวอย่างตัวเลขฐาน 10
ที่เป็นเลขทศนิยมและตัวเลขฐาน
2
ที่เทียบเท่ากันหรือใกล้เคียงกัน
-
เลขฐาน 10เลขฐานสอง0.10.0001100110011.....0.30.0100110011001.....0.50.10.750.110.933593750.11111111
ตัวอย่างในตารางที่
๔ แสดงให้เห็นว่ามีเลขทศนิยมในระบบเลขฐาน
10
บางจำนวนเท่านั้นที่สามารถหาเลขทศนิยมในระบบเลขฐาน
2
ที่มีค่าเท่ากันได้
ตัวเลขเช่น
0.5,
0.25, 0.125, 0.0625 ฯลฯ
เป็นตัวเลขทศนิยมในระบบเลขฐาน
10
ที่สามารถแทนด้วยค่าตัวเลขทศนิยมในระบบเลขฐานสองที่มีค่าเท่ากันได้
ส่วนค่า 0.1
ในระบบเลขฐาน
10
จะมีค่าเป็นทศนิยมไม่รู้จบในระบบเลขฐาน
2
ดังนั้นเมื่อทำการป้อนข้อมูลที่มีค่าเท่ากับ
0.1
ในระบบเลขฐาน10
เข้าไปในคอมพิวเตอร์
คอมพิวเตอร์จะทำการแทนค่าด้วยเลขฐาน
2
ที่มีค่า
"ใกล้เคียง"
กับเลข
0.1
ในระบบเลขฐาน
10
กล่าวอีกนัยหนึ่งคือเรามีความคลาดเคลื่อน
(error)
เกิดขึ้นโดยที่เรายังไม่ได้เริ่มทำการคำนวณเลย
เวลาที่เราสั่งให้คอมพิวเตอร์เก็บค่าตัวเลข
(ที่ไม่มีทศนิยม)
ในรูป
"จำนวนเต็ม"
นั้น
เช่นเลข 100
คอมพิวเตอร์ก็จะแปลงเป็นเลขฐาน
2
คือ
1100100
ซึ่งเป็นจำนวนที่เทียบเท่ากับพอดี
แต่ถ้าเราสั่งให้มันเก็บค่า
100
ในรูปแบบ
"จำนวนจริง"
มันก็จะเก็บค่าในรูปแบบทำนอง
0.1
x 102 (อันที่จริงก็ไม่ใช่แบบนี้
เพียงแต่ต้องการเขียนให้เห็นภาพหน่อย)
ซึ่งถ้าจะว่ากันทางคณิตศาสตร์แล้วมันก็ควรเท่ากับ
100
แต่ปัญหาก็คือเลข
0.1
ในระบบฐาน
10
นั้น
มันไม่มีเลขในระบบฐาน 2
ที่
"เท่ากันพอดี"
สิ่งที่เครื่องมันทำให้ก็คือมันจะหาเลขฐาน
2
ที่ใกล้เคียงที่สุดให้
ส่วนจะใกล้ได้มากแค่ไหนนั้นก็ขึ้นอยู่กับว่าเราใช้จำนวนบิท
(bit)
มากน้อยเท่าใดในการเก็บข้อมูล
ในทำนองเดียวกันถ้าเราให้มันเก็บค่าตัวเลข
0.001
ในระบบฐาน
10
มันก็จะแปลงค่าเป็น
0.1
x 10-2 ซึ่งก็จะมีปัญหาว่ามันจะหาค่าในระบบฐาน
2
ที่ใกล้เคียงที่สุดให้
ผลที่ตามมาก็คือ
เรายังไม่ได้เริ่มทำการคำนวณเลย
เราก็มีความคลาดเคลื่อนในการคำนวณแล้ว
ผลของความคลาดเคลื่อนตรงนี้ทดลองเองได้ไม่ยากครับ
ลองเปิดโปรแกรม spread
sheet ขึ้นมา
แล้วลองป้อนเลข 0.1
เรียงแถวลงไปในคอลัมน์ด้านซ้าย
(เขียนเยอะหลายสิบตัวหน่อย)
จากนั้นก็ลองใช้คำสั่ง
sum
ดูทุก
ๆ 10
จำนวนดูก็ได้ครับ
แล้วดูว่าค่าผลลัพธ์ที่ได้นั้นเป็นอย่างไร
ตารางที่
๕ ผลรวมของค่า 0.1
(คำนวณด้วยโปรแกรม
spread
sheet OpenOffice 4.1.5)
1
|
1.000000000000000E-01
|
|
2
|
1.000000000000000E-01
|
|
---
|
---
|
|
10
|
1.000000000000000E-01
|
1.000000000000000E+00
|
11
|
1.000000000000000E-01
|
|
---
|
---
|
|
20
|
1.000000000000000E-01
|
2.000000000000000E+00
|
21
|
1.000000000000000E-01
|
|
---
|
---
|
|
30
|
1.000000000000000E-01
|
3.000000000000000E+00
|
31
|
1.000000000000000E-01
|
|
---
|
---
|
|
40
|
1.000000000000000E-01
|
4.000000000000000E+00
|
41
|
1.000000000000000E-01
|
|
---
|
---
|
|
50
|
1.000000000000000E-01
|
5.000000000000000E+00
|
51
|
1.000000000000000E-01
|
|
---
|
---
|
|
60
|
1.000000000000000E-01
|
6.000000000000000E+00
|
61
|
1.000000000000000E-01
|
|
---
|
---
|
|
70
|
1.000000000000000E-01
|
6.999999999999990E+00
|
71
|
1.000000000000000E-01
|
|
---
|
---
|
|
80
|
1.000000000000000E-01
|
7.999999999999990E+00
|
ผลการคำนวณที่แสดงในตารางที่ ๕ อันที่จริงเคยทำไว้ตั้งแต่สมัยใช้คอม 16 บิท พอเปลี่ยนเป็น 32 บิทหรือ 64 บิทก็ยังพบปัญหาแบบเดียวกันอยู่ เพียงแต่พบช้าลงเท่านั้นเอง ตอนที่เอา 0.1 จำนวน 10 20 ไปจนถึง 60 ตัวมารวมกัน ผลลรวมออกมาก็เป็น 1 2 3 4 5 และ 6 ดังที่เราคิดว่ามันควรเป็น แต่พอเอา 0.1 จำนวน 70 ตัวมาบวกเข้าด้วยกัน ปรากฏว่าไม่ได้ 7 กลับได้ 6.999999.... และหลังจากนั้นก็ได้ผลที่น้อยกว่าค่าที่ควรจะเป็นเสมอ ส่วนที่ว่าจะเห็นปรากฏการณ์นี้เมื่อใดนั้นขึ้นอยู่กับว่าคุณใช้กี่บิทในการเก็บข้อมูล ถ้าใช้จำนวนบิทมากก็จะเห็นมันเกิดช้าหน่อย แต่ก็ยังเกิดอยู่ดี
ส่วนที่ว่าเครื่องนั้นให้ความละเอียดมากน้อยแค่ไหน
ก็ลองเพิ่มจำนวนจุดทศนิยมให้มันเขียนรายงานผล
ถ้าพบว่าเมื่อใดที่เพิ่มแล้วตำแหน่งท้ายสุดนั้นมันมีค่าเป็น
0
ตลอด
นั่นก็แสดงว่าจุดนั้นมันเกินความละเอียดของเครื่องแล้ว
อย่างในตารางที่ ๕ ก็อยู่ที่
15
ตำแหน่ง
ตารางที่
๖ เป็นอีกตัวอย่างหนึ่งที่จะไปทดลองเล่นดูเองกับโปรแกรม
spread
sheetก็ได้ครับ
ตัวเลข 0.3333...
ในคอลัมน์ข้างซ้ายผมคำนวณด้วยคำสั่ง
1/3
จากนั้นก็นำมาบวกรวมกัน
ส่วนคอลัมน์ข้างขวานั้นผมป้อนตัวเลข
0.3333...
ลงไปโดยตรงโดยให้ตัวเลขที่
"แสดงผลบนหน้าจอ"
เหมือนกับตัวเลขในคอลัมน์ด้านซ้าย
จากนั้นก็นำมาบวกรวมกัน
จะเห็นว่าผลลัพธ์ที่ได้นั้นแตกต่างกันอยู่เล็กน้อยที่ทศนิยมตำแหน่งสุดท้าย
(ที่ไฮไลต์ตัวหนาสีแดงเอาไว้)
นั่นแสดงว่าตัวเลขที่เครื่องแสดงผลออกมาทางหน้าจอ
แม้ว่ามันจะเหมือนกัน
แต่สิ่งที่อยู่ในหน่วยความจำของมันนั้นมันแตกต่างกันอยู่
ตารางที่
๖ ผลรวมของตัวเลขจำนวน 3
จำนวนที่
"เหมือนกัน"
-
คำนวณจาก 1/3
พิมพ์ตัวเลขลงไปโดยตรง
0.333333333333333000
0.333333333333333000
0.333333333333333000
0.333333333333333000รวม0.666666666666667000
0.666666666666666000
ผลจากการที่เครื่องไม่สามารถหาเลขฐาน
2
ที่เทียบเท่ากับเลขทศนิยมในระบบฐาน
10
ได้ทุกจำนวน
ที่ทำให้ผลการคำนวณที่ได้นั้นมีความผิดเพี้ยนไป
จะเห็นได้ชัดเจนและรวดเร็วแค่ไหนนั้นขึ้นอยู่กับว่าเราใช้กี่บิทในการเก็บข้อมูล
ยิ่งใช้บิทมากก็ยิ่งช่วยบรรเทาผลกระทบนี้
แต่ใช้ว่ามันจะหายไป
มันก็ยังมีอยู่ แต่อาจเห็นได้ไม่ชัดเจนนัก
เว้นแต่จะมีจำนวนครั้งการคำนวณที่มาก
(ดังนั้นถ้านำสิ่งที่แนะนำนี้ไปทดสอบด้วยเครื่องคอมพิวเตอร์ต่างระบบกัน
ก็อาจให้ผลที่แตกต่างกันไปได้)
ด้วยเหตุนี้บางโปรแกรมจึงมีคำสั่งให้เพิ่มจำนวนบิทเก็บข้อมูลขึ้นเป็น
2
เท่า
(เช่นคำสั่ง
Double
precision ในภาษา
FORTRAN
ที่ผมเรียนมา)
แต่นั่นก็หมายถึงหน่วยความจำที่ต้องการมากขึ้นและเวลาที่ต้องใช้ในการคำนวณที่เพิ่มมากขึ้นตามไปด้วย
ไม่มีความคิดเห็น:
แสดงความคิดเห็น