จำนวนจุดลอยตัว

จาก testwiki
ไปยังการนำทาง ไปยังการค้นหา
Z3 คอมพิวเตอร์ฐานสองเชิงกลที่สามารถโปรแกรมและดำเนินการทางคณิตศาสตร์ได้เครื่องแรก (จัดแสดงต่อสาธารณะที่พิพิธภัณฑ์เยอรมันในเมืองมิวนิก
ตัวอย่างแสดงถึงการแทนจำนวนจุดลอยตัวโดยแบ่งเป็นการเก็บค่าเลขนัยสำคัญและเลขชี้กำลัง

ในทางคอมพิวเตอร์ จำนวนจุดลอยตัว (แม่แบบ:Langx) คือระบบแทนจำนวนชนิดหนึ่ง ซึ่งจำนวนนั้นอาจมีขนาดใหญ่หรือขนาดเล็กเกินกว่าที่จะแทนด้วยจำนวนเต็ม เนื่องจากจำนวนต่าง ๆ สามารถเขียนแทนด้วยเลขนัยสำคัญ (mantissa) จำนวนหนึ่งโดยประมาณ และเปลี่ยนสเกลด้วยเลขชี้กำลัง (exponent) ฐานของสเกลปกติจะเป็น 2, 10 หรือ 16 เป็นต้น จำนวนทั่วไปจึงสามารถเขียนให้อยู่ในรูปแบบนี้ได้

เลขนัยสำคัญ × ฐาน เลขชี้กำลัง

คำว่า จุดลอยตัว จึงหมายถึงจุดฐาน (จุดทศนิยม หรือในคอมพิวเตอร์คือ จุดทวินิยม[1]) ที่สามารถ "ลอยตัว" ได้ หมายความว่า จุดฐานสามารถวางไว้ที่ตำแหน่งใดก็ได้ที่สัมพันธ์กับเลขนัยสำคัญของจำนวนนั้น ตำแหน่งนี้แสดงไว้แยกต่างหากในข้อมูลภายใน และการแทนด้วยจำนวนจุดลอยตัวจึงอาจถือว่าเป็นสัญกรณ์วิทยาศาสตร์ในบริบทของคอมพิวเตอร์ หลายปีที่ผ่านมา คอมพิวเตอร์ใช้งานจำนวนจุดลอยตัวในรูปแบบที่แตกต่างกัน เวลาต่อมาจึงทำให้เกิดมาตรฐาน IEEE 754 สำหรับจำนวนที่พบได้อย่างปกติสามัญชนิดนี้

ข้อดีของจำนวนจุดลอยตัวที่มีต่อจำนวนจุดตรึง (fixed point รวมทั้งจำนวนเต็ม) คือจำนวนจุดลอยตัวสามารถรองรับค่าได้ในขอบเขตที่กว้างกว่า ตัวอย่างเช่น จำนวนจุดตรึงที่มีตัวเลขเจ็ดหลัก และกำหนดให้สองหลักสุดท้ายอยู่หลังจุด สามารถแทนจำนวนเหล่านี้ได้ 12345.67, 123.45, 1.23 ในขณะที่จำนวนจุดลอยตัว (ตามเลขฐานสิบของมาตรฐาน IEEE 754) ที่มีตัวเลขเจ็ดหลักเช่นกัน สามารถแทนจำนวนเหล่านี้ได้อีกเพิ่มเติม 1.234567, 123456.7, 0.00001234567, 1234567000000000 เป็นต้น แต่ข้อเสียคือรูปแบบของจำนวนจุดลอยตัวจำเป็นต้องใช้หน่วยเก็บข้อมูลมากขึ้นอีกเล็กน้อย (สำหรับเข้ารหัสตำแหน่งของจุดฐาน) ดังนั้นเมื่อจำนวนทั้งสองประเภทเก็บบันทึกอยู่ในที่ที่เหมือนกัน จำนวนจุดลอยตัวจะใช้เนื้อที่มากกว่าเพื่อเพิ่มความเที่ยง (precision)

ความเร็วของการดำเนินการกับจำนวนจุดลอยตัว เป็นการวัดประสิทธิภาพของคอมพิวเตอร์อย่างหนึ่งที่สำคัญในขอบเขตข่ายโปรแกรมประยุกต์ ซึ่งมีหน่วยวัดเป็นฟล็อปส์ (FLOPS - floating-point operations per second การประมวลผลจุดลอยตัวต่อวินาที)

ภาพรวม

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

มีกลไกหลายประเภทที่ใช้สายอักขระของเลขโดดแทนจำนวน ในสัญกรณ์คณิตศาสตร์ทั่วไป สายอักขระของเลขโดดสามารถยาวเท่าใดก็ได้ และตำแหน่งของจุดฐานแสดงไว้โดยการใส่จุดทศนิยม (ซึ่งอาจเป็นมหัพภาคหรือจุลภาค) ไว้ตรงนั้น ถ้าจุดฐานไม่ปรากฏ จะถูกสมมติโดยนัยว่าวางอยู่ทางขวาสุด (นัยสำคัญน้อยสุด) ของสายอักขระของเลขโดด (นั่นคือจำนวนนั้นเป็นจำนวนเต็ม) ในระบบจำนวนจุดตรึง สมมติฐานบางข้อถูกกำหนดขึ้นว่าจุดฐานจะอยู่ที่ตำแหน่งใดของสายอักขระ ตัวอย่างเช่น ข้อตกลงเกิดขึ้นว่าสายอักขระประกอบด้วยเลขโดดฐานสิบ แปดหลัก โดยมีจุดทศนิยมอยู่ตรงกลาง ดังนั้นจำนวน "00012345" จึงหมายถึงค่า 1.2345

ในสัญกรณ์วิทยาศาสตร์ จำนวนที่กำหนดจะเปลี่ยนสเกลด้วยกำลังของ 10 ดังนั้นเลขนัยสำคัญจึงมีค่าอยู่ในช่วงจำเพาะคืออยู่ระหว่าง 1 ถึง 10 โดยจุดฐานจะปรากฏถัดจากเลขโดดตัวแรกทันที ตัวคูณสเกลที่เป็นกำลังของ 10 จะแสดงแยกต่างหากไปที่ท้ายจำนวน ตัวอย่างเช่น เวลาที่ใช้ในการหมุนรอบตัวเองของดวงจันทร์ไอโอของดาวพฤหัสบดีเท่ากับ 152853.5047 วินาที จำนวนนี้สามารถแสดงได้ในสัญกรณ์คณิตศาสตร์รูปแบบมาตรฐานเป็น 1.528535047แม่แบบ:E วินาที

จำนวนจุดลอยตัวเป็นแนวคิดที่คล้ายกับสัญกรณ์คณิตศาสตร์ จึงประกอบด้วยสองส่วนตามหลักเหตุผล

  • สายอักขระของเลขโดดที่มีเครื่องหมายบวกลบ ตามความยาวและฐานที่กำหนด ส่วนนี้เรียกว่า ซิกนิฟิแคนด์ (significand) หรือบางครั้งเรียกว่า แมนทิสซา (mantissa) หรือ สัมประสิทธิ์ จุดฐานนั้นไม่ได้รวมอยู่ด้วย แต่อาจสมมติโดยนัยว่าวางอยู่ที่ใดที่หนึ่งในซิกนิฟิแคนด์ ซึ่งบ่อยครั้งอยู่ก่อนหรือหลังเลขโดดที่มีนัยสำคัญมากสุด หรืออยู่ทางขวาสุดก็ได้ (บทความนี้จะใช้ข้อตกลงว่าจุดฐานอยู่หลังเลขโดดที่มีนัยสำคัญมากสุด) ความยาวของซิกนิฟิแคนด์เป็นตัวพิจารณาความเที่ยงของจำนวนที่ใช้แทน
  • เลขชี้กำลังจำนวนเต็มที่มีเครื่องหมายบวกลบ หรือเรียกว่า แคแรกเทอริสติก (characteristic) หรือสเกล ซึ่งเป็นตัวดัดแปรขนาดมากน้อยของจำนวน

ซิกนิฟิแคนด์ คูณด้วย ฐาน ที่ยกกำลังด้วย เลขชี้กำลัง จะเทียบเท่ากับการเลื่อนจุดฐานจากตำแหน่งสมมติ ไปเป็นจำนวนหลักเท่ากับค่าของเลขชี้กำลัง โดยเลื่อนไปทางขวาถ้าเลขชี้กำลังเป็นบวกหรือไปทางซ้ายถ้าเลขชี้กำลังเป็นลบ

หากอธิบายด้วยเลขฐานสิบอันเป็นสัญกรณ์ที่คุ้นเคย จำนวน 152853.5047 ซึ่งมีเลขโดดฐานสิบ ความเที่ยงสิบหลัก การแทนจำนวนจะได้ 1528535047 เป็นซิกนิฟิแคนด์ และเลขชี้กำลังเป็น 5 (โดยจุดฐานถูกสมมติขึ้นที่หลังเลข 1 ซึ่งเป็นเลขโดดที่มีนัยสำคัญมากสุด) และเพื่อที่จะเรียกคืนค่าแท้จริง จะเติมจุดทศนิยมที่หลังเลขโดดตัวแรกของซิกนิฟิแคนด์ แล้วนำไปคูณด้วย แม่แบบ:10^ จนได้ 1.528535047แม่แบบ:E ซึ่งนั่นก็คือจำนวน 152853.5047 ในการเก็บบันทึกจำนวนเช่นนี้ ฐาน 10 ไม่จำเป็นต้องเก็บบันทึกไปด้วย เนื่องจากมันมีใช้เหมือนกันในทุก ๆ จำนวน และสามารถอนุมานได้ในภายหลัง จำนวนนี้จึงอาจเขียนอย่างง่ายได้เป็น 1.528535047 E 5 ซึ่ง "E" กำหนดให้หมายถึง "คูณด้วยสิบยกกำลัง..." เช่นเดียวกับข้อตกลงอันเป็นที่ทราบ

หากเขียนเป็นสัญลักษณ์ ค่าสุดท้ายที่ได้ออกมาคือ

s×be

เมื่อ s คือซิกนิฟิแคนด์ที่เติมจุดฐานสมมติเข้าไปแล้ว b คือฐาน และ e คือเลขชี้กำลัง

หรือเทียบเท่ากับประโยคนี้

sbp1×be

เมื่อ s คือจำนวนเต็มจากซิกนิฟิแคนด์ทั้งหมดโดยไม่พิจารณาจุดฐานสมมติ ส่วน p คือความเที่ยง (precision) หมายถึงจำนวนหลักของซิกนิฟิแคนด์

ในอดีตที่ผ่านมา ฐานที่แตกต่างกันถูกใช้แทนจำนวนจุดลอยตัว เช่นฐานสองที่เป็นปกติสามัญที่สุด ตามมาด้วยฐานสิบ และฐานสิบหกที่พบได้น้อยกว่า จำนวนจุดลอยตัวถือว่าเป็นจำนวนตรรกยะเพราะมันสามารถเขียนแทนได้ด้วยเศษหนึ่งส่วนจำนวนอื่น อย่างไรก็ตาม ฐานจะเป็นตัวพิจารณาว่าเศษส่วนจะถูกเขียนแทนอย่างไร ตัวอย่างเช่น แม่แบบ:เศษ ไม่สามารถเขียนแทนด้วยจำนวนจุดลอยตัวในฐานสองได้อย่างแม่นยำ แต่สามารถเขียนแทนในฐานสิบได้อย่างถูกต้อง

วิธีการที่ซิกนิฟิแคนด์ เลขชี้กำลัง และบิตเครื่องหมายถูกเก็บบันทึกภายในคอมพิวเตอร์ขึ้นอยู่กับวิธีการทำให้เกิดผล รูปแบบปกติของ IEEE ได้อธิบายรายละเอียดในเวลาต่อมา ตัวอย่างเช่น การแทนจำนวนจุดลอยตัวฐานสองขนาดความเที่ยงหนึ่งเท่า (32 บิต) ซึ่งมีความเที่ยง p = 24 หมายความว่าจะเก็บบันทึกซิกนิฟิแคนด์ได้เป็นสายอักขระ 24 บิต (ประกอบด้วย 0 และ 1) กำหนดให้ค่าของพาย 33 บิตแรกคือ 11001001 00001111 11011010 10100010 0 การปัดเศษให้เหลือ 24 บิตในฐานสองทำได้โดยเพิ่มค่าบิตที่ 24 ซึ่งกระจายมาจากบิตที่ 25 จะได้ 11001001 00001111 11011011 เมื่อเก็บบันทึกในการเข้ารหัส IEEE 754 จำนวนนี้จะกลายเป็นซิกนิฟิแคนด์ s โดยที่ e = 1 (เมื่อสมมติให้จุดทวินิยมอยู่หลังบิตแรกสุดใน s) หลังจากมีการปรับค่าเข้าสู่ทางซ้ายแล้วซึ่งจะทำให้เลขศูนย์นำหน้าหรือตามหลังจำนวนถูกตัดออกถ้ามี (แต่จากตัวอย่างนี้ไม่เกิดผลใด ๆ) ดังนั้นบิตแรกสุดของซิกนิฟิแคนด์จึงเป็น 1 เสมอ (หากค่านั้นไม่ใช่การแทนจำนวน 0) ทำให้เกิดบิตเพิ่มเติมของความเที่ยงซึ่งไม่จำเป็นต้องเก็บบันทึก ค่าของพายจึงคำนวณได้จากสูตร

(1+n=1p1bitn×2n)×2e
=(1+1×21+0×22+1×24+1×27++1×223)×21
=1.5707964×2

เมื่อ n คือบิตที่ n จากทางซ้ายของซิกนิฟิแคนด์ที่ปรับแต่งแล้ว การปรับแต่งซิกนิฟิแคนด์หรือเรียกว่า การทำให้เป็นบรรทัดฐาน (normalization) คือการสงวนค่า 1 ที่บวกเข้าไปในภายหลัง และอาจเรียกได้ว่าเป็นรูปแบบหนึ่งของการบีบอัด นั่นคือซิกนิฟิแคนด์ฐานสองจะย่อลงจากเดิมหนึ่งบิตจากความเที่ยงมากสุด ในการประมวลผลเพิ่มเติม

คำว่า แมนทิสซา มักจะใช้เรียกเป็นคำคล้ายกับซิกนิฟิแคนด์แม้ว่ามันจะไม่ถูกต้องนัก เนื่องจากแมนทิสซาในความหมายดั้งเดิมนิยามขึ้นจากส่วนจำนวนเศษของลอการิทึม ในขณะที่ แคแรกเทอริสติก ก็เป็นส่วนจำนวนเต็มของลอการิทึม คำนี้ปรากฏอยู่ในตารางลอการิทึมก่อนที่จะมีคอมพิวเตอร์ใช้กันทั่วไป ตารางลอการิทึมความจริงแล้วก็คือตารางของแมนทิสซา ดังนั้นแมนทิสซาจึงเป็นลอการิทึมของซิกนิฟิแคนด์

การแทนจำนวนที่ไม่ใช่จำนวนเต็มชนิดอื่นในคอมพิวเตอร์

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

  • จำนวนจุดตรึง เป็นการแทนจำนวนที่ใช้การดำเนินการฮาร์ดแวร์จำนวนเต็ม ควบคุมโดยซอฟต์แวร์ที่มีข้อตกลงจำเพาะเกี่ยวกับตำแหน่งของจุดทศนิยมหรือจุดทวินิยม เช่น หกหลักหรือหกบิตจากทางขวา เป็นต้น ฮาร์ดแวร์ที่จัดดำเนินการการแทนจำนวนเช่นนี้ใช้ทรัพยากรน้อยกว่าจำนวนจุดลอยตัว และใช้สำหรับดำเนินการจำนวนเต็ม จำนวนจุดตรึงฐานสองปกติจะใช้ในโปรแกรมประยุกต์ที่มีจุดประสงค์พิเศษ ในตัวประมวลผลฝังตัวที่สามารถคำนวณได้แค่เลขคณิตจำนวนเต็ม แต่จำนวนจุดตรึงฐานสิบจะใช้กับโปรแกรมประยุกต์เชิงพาณิชย์
  • เลขฐานสิบเข้ารหัสฐานสอง เป็นการเข้ารหัสเลขฐานสิบซึ่งเลขโดดแต่ละหลักจะถูกแทนด้วยลำดับฐานสองของมันเอง
  • หากต้องการความเที่ยงสูงขึ้น เลขคณิตสำหรับจำนวนจุดลอยตัวสามารถสร้างขึ้นได้ (โดยทั่วไปคือในซอฟต์แวร์) ที่มีซิกนิฟิแคนด์แปรความยาวได้ (หรือรวมทั้งเลขชี้กำลังด้วย) ซึ่งจะถูกกำหนดขนาดตามความจำเป็นที่ใช้จริงและตามการดำเนินการคำนวณ สิ่งนี้เรียกว่า เลขคณิตกำหนดความเที่ยงได้ (arbitrary-precision arithmetic)
  • จำนวนบางจำนวนไม่สามารถแทนได้อย่างแม่นยำในจำนวนจุดลอยตัวไม่ว่าจะกำหนดความเที่ยงเท่าใด (เช่น แม่แบบ:เศษ และ 0.1) แพกเกจซอฟต์แวร์ที่ดำเนินการเลขคณิตจำนวนตรรกยะ จะแทนที่จำนวนต่าง ๆ เป็นเศษส่วนโดยมีตัวเศษและตัวส่วนเป็นจำนวนเต็ม จึงสามารถให้ผลเป็นจำนวนตรรกยะใด ๆ ได้อย่างถูกต้อง แพกเกจเช่นนั้นจำเป็นต้องใช้เลขคณิตสำหรับจำนวนขนาดใหญ่ (bignum) สำหรับจำนวนเต็มแต่ละจำนวน
  • ระบบพีชคณิตคอมพิวเตอร์ อย่างเช่นแมทเทอแมติกาหรือแมกซิมา สามารถจัดการกับจำนวนอตรรกยะอย่างเช่น π หรือ √3 ด้วยวิธีการแบบรูปนัยอย่างสมบูรณ์ โดยไม่ต้องยุ่งกับการเข้ารหัสซิกนิฟิแคนด์ โปรแกรมเหล่านี้จะคำนวณนิพจน์อย่างเช่น sin 3π ได้อย่างแม่นยำ เพราะโปรแกรมทราบถึงคณิตศาสตร์ที่เป็นรากฐาน
  • การแทนจำนวนโดยใช้พื้นฐานจากลอการิทึมธรรมชาติบางครั้งพบได้ในโปรแกรมประยุกต์ในเอฟพีจีเอ ที่ซึ่งการดำเนินการเลขคณิตส่วนใหญ่เป็นการคูณและการหาร[2] แนวทางนี้มีความเที่ยงสำหรับจำนวนขนาดเล็กและรองรับช่วงค่ากว้าง เช่นเดียวกับจำนวนจุดลอยตัว

พิสัยของจำนวนจุดลอยตัว

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

0.12 × 0.12 = 0.0144

เมื่อเขียนแทนในระบบจำนวนจุดลอยตัวฐานสิบ ซึ่งมีเลขโดดสามหลัก จะได้

(1.2แม่แบบ:E) × (1.2แม่แบบ:E) = (1.44แม่แบบ:E)

ในขณะที่ระบบจำนวนจุดตรึงที่มีจุดทศนิยมอยู่ทางซ้ายสุด ซึ่งมีเลขโดดสามหลักเช่นกัน จะได้

0.120 × 0.120 = 0.014

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

พิสัยของจำนวนจุดลอยตัวจึงขึ้นอยู่กับจำนวนบิตหรือเลขโดดที่ใช้สำหรับแทนซิกนิฟิแคนด์ (เลขนัยสำคัญของจำนวน) และเลขชี้กำลัง การแทนจำนวนจุดลอยตัวฐานสองขนาดความเที่ยงสองเท่า (64 บิต) ในระบบคอมพิวเตอร์ทั่วไป จะมีสัมประสิทธิ์ 53 บิต (ซึ่งบิตแรกสุดไม่ต้องเก็บบันทึก) เลขชี้กำลัง 11 บิต และบิตเครื่องหมายอีกหนึ่งบิต จำนวนจุดลอยตัวที่เป็นค่าบวกในรูปแบบนี้จึงมีพิสัยอยู่ที่ประมาณ แม่แบบ:10^ ถึง แม่แบบ:10^ (ค่า 308 มาจาก 1023 × log10 (2) โดยประมาณ และพิสัยของเลขชี้กำลังอยู่ในช่วง [−1022, 1023]) พิสัยโดยรวมทั้งหมดของรูปแบบนี้จึงเก็บบันทึกได้ตั้งแต่ −แม่แบบ:10^ ไปจนถึง +แม่แบบ:10^ (ดูเพิ่มที่ IEEE 754)

จำนวนทั้งหมดของจำนวนจุดลอยตัวที่เป็นบรรทัดฐานแล้วในระบบ F(B, P, L, U) คือ 2(B1)(BP1)(UL+1) เมื่อ B คือฐานของระบบเลข P คือความเที่ยงของระบบ L คือเลขชี้กำลังน้อยสุดที่สามารถแทนได้ในระบบ และ U คือเลขชี้กำลังมากสุดที่สามารถแทนได้ในระบบ

จำนวนจุดลอยตัวที่เป็นบรรทัดฐานแล้วที่เล็กที่สุดในค่าบวก เรียกว่า ระดับน้อยเกินเก็บ (underflow level) คือ UFL=BL ซึ่งจะมีเลขโดด 1 เป็นตัวนำและ 0 สำหรับหลักที่เหลือทั้งหมดในซิกนิฟิแคนด์ และค่าที่น้อยที่สุดที่เป็นไปได้ของเลขชี้กำลัง

จำนวนจุดลอยตัวที่เป็นบรรทัดฐานแล้วที่ใหญ่ที่สุด เรียกว่า ระดับมากเกินเก็บ (overflow level) คือ OFL=(1BP)(BU+1) ซึ่งจะมีเลขโดด B − 1 สำหรับทุกหลักในซิกนิฟิแคนด์ และค่าที่มากที่สุดที่เป็นไปได้ของเลขชี้กำลัง

นอกจากนี้ก็มีค่าระหว่าง −UFL และ UFL ที่สามารถแทนได้ ซึ่งนั่นก็คือ 0 และ −0 รวมทั้งจำนวนต่ำกว่าบรรทัดฐาน (subnormal number)

ประวัติ

คอนรัด ทซูเซอ สถาปนิกผู้ประดิษฐ์คอมพิวเตอร์ฐานสองเชิงกลที่สามารถโปรแกรมได้เครื่องแรก ซึ่งทำงานด้วยจำนวนจุดลอยตัวฐานสอง 22 บิต

เมื่อ พ.ศ. 2481 คอนรัด ทซูเซอ (Konrad Zuse) จากเบอร์ลิน ประดิษฐ์คอมพิวเตอร์ฐานสองเชิงกลที่สามารถโปรแกรมได้เครื่องแรกชื่อ Z1 ทำงานด้วยจำนวนจุดลอยตัวฐานสอง 22 บิต โดยมีเลขชี้กำลังแบบมีเครื่องหมาย 7 บิต ซิกนิฟิแคนด์ 15 บิต (รวมหนึ่งบิตที่ซ่อนไว้) และบิตเครื่องหมาย 1 บิต หน่วยความจำใช้ส่วนโลหะเลื่อนไปมาเพื่อเก็บบันทึกจำนวนเช่นนั้นได้ 64 จำนวน ต่อมาเครื่อง Z3 ที่พัฒนาด้วยรีเลย์ถูกสร้างขึ้นใน พ.ศ. 2484 ได้พัฒนาเลขคณิตของจำนวนจุดลอยตัวให้เกิดผล ยกเว้นการแทนจำนวนสำหรับค่าอนันต์บวกลบและค่าที่ไม่นิยาม[3]

คอมพิวเตอร์ เชิงพาณิชย์ เครื่องแรกที่มีฮาร์ดแวร์จำนวนจุดลอยตัวคือ Z4 ของทซูเซอ ออกแบบและสร้างขึ้นระหว่าง พ.ศ. 2485–2488 คอมพิวเตอร์มาร์ก V ของเบลล์แลบอลาทอรีส์ใช้งานจำนวนจุดลอยตัวฐานสิบใน พ.ศ. 2489 เวลาต่อมาเกือบทศวรรษคือ พ.ศ. 2497 คอมพิวเตอร์ไอบีเอ็ม 704 ซึ่งใช้หลอดสุญญากาศถูกสร้างขึ้นเพื่อจำหน่ายจำนวนมาก คอมพิวเตอร์รุ่นดังกล่าวได้แนะนำการใช้งานเลขชี้กำลังแบบไบแอส หลายทศวรรษหลังจากนั้น ฮาร์ดแวร์จำนวนจุดลอยตัวเป็นคุณลักษณะทางเลือก และคอมพิวเตอร์ที่มีคุณลักษณะนี้ถูกเรียกว่า "คอมพิวเตอร์วิทยาศาสตร์" หรือมีความสามารถใน "การคำนวณทางวิทยาศาสตร์" ไม่บรรจุเป็นมาตรฐาน จนกระทั่ง พ.ศ. 2532 คอมพิวเตอร์สำหรับ จุดประสงค์ทั่วไป มีความสามารถเกี่ยวกับจำนวนจุดลอยตัวในฮาร์ดแวร์เป็นมาตรฐาน

ชุดคอมพิวเตอร์ยูนิแวก 1100/2200 แนะนำขึ้นเมื่อ พ.ศ. 2505 รองรับรูปแบบจำนวนจุดลอยตัวได้สองรูปแบบ คือความเที่ยงหนึ่งเท่า ซึ่งใช้ 36 บิต แบ่งเป็นบิตเครื่องหมาย 1 บิต เลขชี้กำลัง 8 บิต และซิกนิฟิแคนด์ 27 บิต และความเที่ยงสองเท่า ซึ่งใช้ 72 บิต แบ่งเป็นบิตเครื่องหมาย 1 บิต เลขชี้กำลัง 11 บิต และซิกนิฟิแคนด์ 60 บิต คอมพิวเตอร์ไอบีเอ็ม 7094 แนะนำขึ้นในปีเดียวกัน รองรับทั้งความเที่ยงหนึ่งเท่าและสองเท่า แต่มีรูปแบบที่ต่างไปเล็กน้อย

ก่อนที่จะมีมาตรฐาน IEEE 754 คอมพิวเตอร์ต่าง ๆ ใช้รูปแบบจำนวนจุดลอยตัวในรูปแบบที่ต่างกันมากมาย ซึ่งต่างกันที่ขนาดของเวิร์ด รูปแบบของการแทน และพฤติกรรมการปัดเศษของการดำเนินการ ระบบต่าง ๆ ที่แตกต่างกันนี้ทำให้เกิดการพัฒนาเลขคณิตในฮาร์ดแวร์และซอฟต์แวร์แตกต่างกัน ด้วยความเที่ยงตรงแม่นยำที่ไม่เหมือนกัน

มาตรฐาน IEEE 754 สร้างขึ้นเมื่อ พ.ศ. 2528 หลังจากขนาดของเวิร์ด 32 บิต (หรือ 16 หรือ 64) ได้รับการยอมรับโดยทั่วไป ซึ่งมีพื้นฐานมาจากข้อเสนอของอินเทล ผู้พัฒนาตัวประมวลผลร่วมเชิงตัวเลข อินเทล 8087 ในขณะนั้น[4] นวัตกรรมที่เกิดขึ้นใหม่คือสิ่งเหล่านี้

  • การเข้ารหัสบิตต่าง ๆ ระบุไว้อย่างชัดเจน ดังนั้นคอมพิวเตอร์ทุกเครื่องที่ยอมรับจะสามารถแปลผลรูปแบบบิตไปในทางเดียวกัน สิ่งนี้ทำให้สามารถส่งผ่านจำนวนจุดลอยตัวกับคอมพิวเตอร์เครื่องอื่นได้
  • พฤติกรรมของการดำเนินการเลขคณิตระบุไว้อย่างชัดเจน สิ่งนี้ทำให้โปรแกรมและค่าที่กำหนด สร้างผลลัพธ์ได้เหมือนกันในคอมพิวเตอร์เครื่องใด ๆ ที่ยอมรับ และช่วยลดความเชื่อว่า การคำนวณจำนวนจุดลอยตัวมีไว้สำหรับพฤติกรรมที่ประหนึ่งว่ากำหนดพิจารณาไม่ได้
  • ความสามารถของเงื่อนไขพิเศษ (เช่นภาวะมากเกินเก็บ การหารด้วยศูนย์ ฯลฯ) เพื่อแจ้งผ่านการคำนวณที่ละเอียดอ่อน และจัดการควบคุมได้โดยซอฟต์แวร์

IEEE 754: จำนวนจุดลอยตัวในคอมพิวเตอร์สมัยใหม่

แม่แบบ:บทความหลัก สถาบันวิชาชีพวิศวกรไฟฟ้าและอิเล็กทรอนิกส์ (IEEE) ได้กำหนดมาตรฐานสำหรับการแทนจำนวนจุดลอยตัวฐานสองใน IEEE 754 คอมพิวเตอร์สมัยใหม่เกือบทั้งหมดทำตามมาตรฐานนี้ ข้อยกเว้นที่โดดเด่นคือคอมพิวเตอร์เมนเฟรมของไอบีเอ็ม ซึ่งใช้รูปแบบของมันเอง (สถาปัตยกรรมจุดลอยตัวของไอบีเอ็ม เพิ่มเติมจากรูปแบบฐานสองและฐานสิบจาก IEEE 754) และคอมพิวเตอร์เครย์ ซึ่งรุ่น T90 ใช้ตามรูปแบบของ IEEE แต่รุ่น SV1 ยังคงใช้รูปแบบของมันเอง

แม่แบบ:จำนวนจุดลอยตัว

มาตรฐานนี้กำหนดรูปแบบหลายชนิดที่เกี่ยวข้องอย่างใกล้ชิด ต่างกันที่รายละเอียดเพียงเล็กน้อย มีห้ารูปแบบเรียกว่า รูปแบบพื้นฐาน และมีอีกสองรูปแบบเป็นรูปแบบที่ใช้อย่างกว้างขวางในฮาร์ดแวร์คอมพิวเตอร์และภาษาโปรแกรมโดยเฉพาะได้แก่

  • ความเที่ยงหนึ่งเท่า (single precision) ในตระกูลภาษาซีเรียกว่า "float" และในภาษาฟอร์แทรนเรียกว่า "real" หรือ "real*4" รูปแบบนี้เป็นฐานสองใช้เนื้อที่ 32 บิต (4 ไบต์) และซิกนิฟิแคนด์มีความเที่ยงขนาด 24 บิต (เลขโดดฐานสิบประมาณ 7 หลัก)
  • ความเที่ยงสองเท่า (double precision) ในตระกูลภาษาซีเรียกว่า "double" และในภาษาฟอร์แทรนเรียกว่า "double precision" หรือ "real*8" รูปแบบนี้เป็นฐานสองใช้เนื้อที่ 64 บิต (8 ไบต์) และซิกนิฟิแคนด์มีความเที่ยงขนาด 53 บิต (เลขโดดฐานสิบประมาณ 16 หลัก)

รูปแบบพื้นฐานอื่นเช่น ความเที่ยงสี่เท่า (quadruple precision) ฐานสอง (128 บิต) จำนวนจุดลอยตัวฐานสิบ (64 บิต) และจำนวนจุดลอยตัวฐานสิบความเที่ยงสองเท่า (128 บิต) เป็นต้น

รูปแบบที่พบได้น้อยกว่าปกติเช่น

  • รูปแบบความเที่ยงแบบขยาย เก็บค่าจำนวนจุดลอยตัว 80 บิต บางครั้งเรียกว่า "long double" ในตระกูลภาษาซี แม้คำว่า "long double" อาจมีความหมายเหมือนกับ "double" หรือใช้แทนความหมายของความเที่ยงสี่เท่า
  • ความเที่ยงครึ่งเท่า เก็บค่าจำนวนจุดลอยตัว 16 บิต

จำนวนเต็มใด ๆ ที่มีค่าสัมบูรณ์น้อยกว่าหรือเท่ากับ 224 สามารถแทนในรูปแบบความเที่ยงหนึ่งเท่า และน้อยกว่าหรือเท่ากับ 253 สามารถแทนในรูปแบบความเที่ยงสองเท่า ยิ่งไปกว่านั้น พิสัยอย่างกว้างของกำลังของสอง คูณด้วยจำนวนเช่นนั้นก็สามารถแทนค่าได้ สมบัติเหล่านี้บางครั้งใช้กับข้อมูลจำนวนเต็มเพียงอย่างเดียว เพื่อให้ได้ผลลัพธ์เป็นจำนวนเต็ม 53 บิต บนแพลตฟอร์มที่มีระบบจำนวนจุดลอยตัวความเที่ยงสองเท่า แต่มีระบบจำนวนเต็มเพียง 32 บิต เป็นตัวอย่าง

มาตรฐานนี้ระบุค่าพิเศษบางค่าไว้ด้วยพร้อมทั้งการแทนจำนวน ได้แก่ อนันต์บวก (+∞) อนันต์ลบ (−∞) ลบศูนย์ (−0) ซึ่งต่างจากศูนย์ธรรมดา และค่าไม่ใช่จำนวน (แม่แบบ:Langx)

การเปรียบเทียบจำนวนจุดลอยตัวก็ได้กำหนดไว้ในมาตรฐาน IEEE ซึ่งต่างจากการเปรียบเทียบจำนวนเต็มตามปกติเล็กน้อย นั่นคือลบศูนย์กับบวกศูนย์ถือว่าเท่ากัน และ NaN ไม่เท่ากับจำนวนใด ๆ เลยรวมทั้งตัวมันเองด้วย นอกเหนือจากกรณีพิเศษเหล่านี้ บิตที่มีนัยสำคัญมากกว่าจะถูกเก็บบันทึกก่อนบิตที่มีนัยสำคัญน้อยกว่า ค่าทุกค่ายกเว้น NaN ถือว่าน้อยกว่า +∞ และมากกว่า −∞ อย่างเคร่งครัด

การแทนค่าบิตของจำนวนจุดลอยตัวฐานสองจะแปรตามลอการิทึมฐานสองเพื่อการประมาณค่าอย่างหยาบ ด้วยความคลาดเคลื่อนเฉลี่ยประมาณ 3% (เพราะว่าเขตข้อมูลเลขชี้กำลังอยู่ในส่วนที่มีนัยสำคัญมากกว่าของข้อมูล) สิ่งนี้สามารถใช้ประโยชน์ได้ในโปรแกรมประยุกต์บางโปรแกรม เช่นการปรับความดังในการประมวลผลเสียงดิจิทัล

แม้ว่ารูปแบบ 32 บิต (หนึ่งเท่า) และ 64 บิต (สองเท่า) เป็นรูปแบบสามัญที่สุดในวงกว้าง มาตรฐานนี้ก็อนุญาตให้ใช้ระดับความเที่ยงที่ต่างกันหลายระดับ ฮาร์ดแวร์คอมพิวเตอร์ (อาทิชุดคอมพิวเตอร์อินเทล เพนเทียม และชุดคอมพิวเตอร์โมโตโรลา 68000) มักจะเตรียมรูปแบบความเที่ยงแบบขยาย 80 บิตไว้ให้ โดยมีเลขชี้กำลัง 15 บิต ซิกนิฟิแคนด์ 64 บิต และไม่มีบิตที่ซ่อนไว้

มีการโต้เถียงเกี่ยวกับความล้มเหลวของภาษาโปรแกรมส่วนใหญ่ ที่ไม่สามารถทำรูปแบบความเที่ยงแบบขยายให้โปรแกรมเมอร์ใช้ (ถึงแม้ภาษาซีและภาษาที่เกี่ยวข้อง มักจะเตรียมรูปแบบเหล่านี้ด้วยชนิดข้อมูล long double บนฮาร์ดแวร์เช่นนั้น) ผู้จำหน่ายระบบอาจเตรียมรูปแบบขยายเพิ่มเติม (เช่น 128 บิต) แล้วจำลองการทำงานในซอฟต์แวร์

โครงการปรับปรุงแก้ไขมาตรฐาน IEEE 754 เริ่มขึ้นในปี พ.ศ. 2543 แล้วเสร็จและอนุมัติในเดือนมิถุนายน พ.ศ. 2551 มาตรฐานนี้มีรูปแบบจำนวนจุดลอยตัวฐานสิบหลายแบบ และจำนวนจุดลอยตัวฐานสอง 16 บิตหนึ่งแบบ (binary16) จำนวนจุดลอยตัวฐานสอง 16 บิตมีโครงสร้างและกฎเหมือนรูปแบบของเดิม มีใช้ในภาษาซีจีของเอ็นวิเดียและมาตรฐาน openEXR[5]

การแทนค่าภายใน

โดยทั่วไปจำนวนจุดลอยตัวบรรจุอยู่ในข้อมูลคอมพิวเตอร์ เป็นบิตเครื่องหมาย เขตข้อมูลเลขชี้กำลัง และเขตข้อมูลซิกนิฟิแคนด์ (แมนทิสซา) ตามลำดับจากซ้ายไปขวา สำหรับรูปแบบ IEEE 754 ในฐานสองจะถูกแบ่งสรรดังนี้

ชนิด เครื่องหมาย เลขชี้กำลัง ซิกนิฟิแคนด์ บิตทั้งหมด ไบแอสของเลขชี้กำลัง ความเที่ยงของบิต
ความเที่ยงครึ่งเท่า 1 5 10 16 15 11
ความเที่ยงหนึ่งเท่า 1 8 23 32 127 24
ความเที่ยงสองเท่า 1 11 52 64 1023 53
ความเที่ยงสี่เท่า 1 15 112 128 16383 113

เมื่อเลขชี้กำลังเป็นบวกหรือลบ จะเก็บบันทึกเป็นจำนวนไม่มีเครื่องหมายซึ่งบวกไบแอส (bias) แบบคงที่เข้าไป (เช่นค่า −9 บวกด้วยไบแอส 15 จะเก็บเป็นค่า 6) เมื่อเลขชี้กำลังเป็น 0 ทุกบิต จะสงวนไว้สำหรับค่าศูนย์และจำนวนต่ำกว่าบรรทัดฐาน และเมื่อเลขชี้กำลังเป็น 1 ทุกบิต จะสงวนไว้สำหรับค่าอนันต์และ NaN พิสัยของเลขชี้กำลังของจำนวนบรรทัดฐานคือ [−126, 127] สำหรับความเที่ยงหนึ่งเท่า [−1022, 1023] สำหรับความเที่ยงสองเท่า ฯลฯ จำนวนบรรทัดฐานไม่รวมค่าทั้งสี่ประเภทได้แก่ ศูนย์ จำนวนต่ำกว่าบรรทัดฐาน อนันต์ และ NaN

ในรูปแบบเพื่อการแลกเปลี่ยนข้อมูลฐานสองของ IEEE บิตแรกสุดของซิกนิฟิแคนด์ที่ทำให้เป็นบรรทัดฐานแล้วซึ่งเป็น 1 ความจริงแล้วจะไม่ถูกเก็บบันทึกในข้อมูลคอมพิวเตอร์ บิตนี้เรียกว่า "บิตที่ซ่อน" หรือ "บิตโดยนัย" ด้วยเหตุนี้ความเที่ยงจึงเพิ่มขึ้น 1 บิตจากซิกนิฟิแคนด์ที่เก็บบันทึก รูปแบบความเที่ยงหนึ่งเท่าจึงมีความเที่ยงแท้จริง 24 บิต รูปแบบความเที่ยงสองเท่ามี 53 บิต ฯลฯ

ตัวอย่างเช่น จำนวนต่อไปนี้คือค่า π ในฐานสอง ปัดเศษที่ความเที่ยง 24 บิต จะได้

  • เครื่องหมาย = 0 ; e = 1 ; s = 110010010000111111011011 (บิตแรกสุดคือบิตที่ซ่อน)

ในรูปแบบความเที่ยงหนึ่งเท่า ผลบวกระหว่างเลขชี้กำลัง 1 กับไบแอส 127 คือ 128 (10000000) ดังนั้นจะแทนค่าได้เป็น

  • 0 10000000 10010010000111111011011 (ตัดบิตที่ซ่อนออก) = 40490FDB ในเลขฐานสิบหก[6]

จำนวนพิเศษ

ศูนย์มีเครื่องหมาย

แม่แบบ:บทความหลัก ในมาตรฐาน IEEE 754 ค่าศูนย์มีเครื่องหมาย หมายความว่ามีทั้ง "บวกศูนย์" (+0) และ "ลบศูนย์" (−0) ในสภาวะแวดล้อมขณะทำงานส่วนใหญ่ ค่าบวกศูนย์โดยทั่วไปพิมพ์เป็น "0" และค่าลบศูนย์อาจพิมพ์เป็น "-0" จำนวนทั้งสองมีความเท่ากันในการเปรียบเทียบเชิงจำนวน แต่การดำเนินการบางอย่างกับ +0 และ −0 จะให้ผลลัพธ์ที่ต่างออกไป ตัวอย่างเช่น 1 / (−0) จะให้ผลเป็นค่าอนันต์ที่เป็นลบ ในขณะที่ 1 / (+0) จะให้ผลเป็นค่าอนันต์ที่เป็นบวก อย่างไรก็ตามการดำเนินการดังกล่าวจะเกิดขึ้นพร้อมกับสิ่งผิดปรกติ "การหารด้วยศูนย์" หรืออีกตัวอย่างหนึ่ง การดำเนินการ arccot สมมาตรมีเครื่องหมาย จะให้ผลลัพธ์ต่างกับสำหรับ +0 และ −0 โดยไม่มีสิ่งผิดปรกติ ความแตกต่างระหว่าง +0 และ −0 เป็นที่สังเกตได้มากที่สุดในการดำเนินการเชิงซ้อนที่ส่วนตัดแบรนช์ (branch cut)

จำนวนต่ำกว่าบรรทัดฐาน

แม่แบบ:บทความหลัก จำนวนต่ำกว่าบรรทัดฐาน (subnormal number) เป็นจำนวนที่เติมในช่องว่างน้อยเกินเก็บ (underflow gap) ด้วยค่าซึ่งระยะห่างสัมบูรณ์ระหว่างจำนวนต่ำกว่าบรรทัดฐาน เหมือนกับจำนวนอื่นที่อยู่ติดกันนอกช่องว่างน้อยเกินเก็บนี้ สิ่งนี้เป็นการปรับปรุงการปฏิบัติแบบเก่าซึ่งให้ค่าเป็นศูนย์เท่านั้นภายในช่องว่างน้อยเกินเก็บ และผลลัพธ์ที่น้อยเกินเก็บถูกแทนที่ด้วยศูนย์ (ถูกปัดเศษทิ้งเป็นศูนย์)

ฮาร์ดแวร์จำนวนจุดลอยตัวสมัยใหม่สามารถจัดการจำนวนต่ำกว่าบรรทัดฐานเหล่านี้ได้ เช่นเดียวกับจำนวนบรรทัดฐาน และไม่ต้องการการจำลองจากซอฟต์แวร์

อนันต์

รายละเอียดเพิ่มเติมเกี่ยวกับแนวคิดของอนันต์ ดูที่ อนันต์

อนันต์บนเส้นจำนวนจริงขยายสามารถแทนได้ในชนิดข้อมูลจำนวนจุดลอยตัว IEEE เช่นเดียวกับจำนวนจุดลอยตัวทั่วไปอย่าง 1 หรือ 1.5 ค่านี้ไม่ใช่ค่าที่เกิดความผิดพลาด ถึงแม้ว่ามันจะใช้แทนค่าที่มากเกินเก็บ (overflow) (แต่ไม่เสมอไป ขึ้นอยู่กับการปัดเศษ) เมื่อเกิดสิ่งผิดปรกติของการหารด้วยศูนย์ จะคืนค่าอนันต์ที่เป็นบวกหรือลบออกมาเป็นผลลัพธ์ ค่าอนันต์สามารถแนะนำให้เป็นจำนวนจำนวนหนึ่ง (เหมือนแมโคร INFINITY ของภาษาซี หรือ ∞ ถ้าภาษาโปรแกรมนั้นอนุญาตให้ใช้ได้)

IEEE 754 ต้องการการจัดการอนันต์อย่างสมเหตุสมผล ตัวอย่างเช่น

  • (+∞) + (+7) = (+∞)
  • (+∞) × (−2) = (−∞)
  • (+∞) × 0 = NaN (ไม่มีความหมาย)

ค่าไม่ใช่จำนวน

แม่แบบ:บทความหลัก IEEE 754 ระบุค่าพิเศษอีกอย่างหนึ่งคือค่าไม่ใช่จำนวน (แม่แบบ:Langx) เพื่อคืนค่าเป็นผลลัพธ์สำหรับการดำเนินการที่ "ไม่สมเหตุสมผล" ตัวอย่างเช่น 0/0, ∞×0, sqrt(−1) เป็นต้น NaN แท้จริงแล้วมีสองชนิดคือ signaling และ quiet การใช้ signaling NaN ในการดำเนินการเลขคณิตใด ๆ (รวมทั้งการเปรียบเทียบเชิงจำนวน) ทำให้เกิดสิ่งผิดปรกติ "ไม่สมเหตุสมผล" ส่วนการใช้ quiet NaN จะได้ผลลัพธ์เป็น NaN เท่านั้นโดยไม่เกิดสิ่งผิดปรกติ

การแทนค่า NaN ที่กำหนดโดยมาตรฐาน มีบางบิตที่ไม่ระบุซึ่งอาจใช้เข้ารหัสชนิดของข้อผิดพลาดได้ แต่ก็ไม่มีมาตรฐานสำหรับการเข้ารหัสนี้ ในทางทฤษฎี signaling NaN สามารถใช้กับระบบขณะทำงาน (runtime system) เพื่อขยายจำนวนจุดลอยตัวด้วยค่าพิเศษอื่น โดยไม่ต้องชะลอการคำนวณกับจำนวนธรรมดา แม้ว่าการขยายเช่นนั้นดูเหมือนว่าไม่เป็นสิ่งปกติสามัญ

จำนวนที่แทนได้ การแปลง และการปัดเศษ

โดยธรรมชาติแล้ว จำนวนทุกจำนวนที่สามารถเขียนให้อยู่ในรูปแบบจำนวนจุดลอยตัว เป็นจำนวนตรรกยะที่มีจุดฐานรู้จบในฐานที่สัมพันธ์กัน (เช่นทศนิยมรู้จบในฐานสิบ หรือทวินิยมรู้จบในฐานสอง) ส่วนจำนวนอตรรกยะอย่างเช่น π หรือ √2 หรือจำนวนตรรกยะที่มีจุดฐานไม่รู้จบต้องใช้เป็นค่าประมาณ จำนวนของเลขโดด (หรือบิต) ของความเที่ยงก็เป็นตัวจำกัดเซตของจำนวนตรรกยะที่สามารถแทนค่าได้อย่างแม่นยำ ตัวอย่างเช่น จำนวน 123456789 จะไม่สามารถแทนค่าได้อย่างแม่นยำถ้ามีความเที่ยงบนเลขโดดฐานสิบเพียงแปดหลัก เป็นต้น

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

จำนวนตรรกยะไม่จำเป็นว่าต้องมีจุดฐานรู้จบในฐานที่สัมพันธ์กัน ตัวอย่างเช่น จำนวน แม่แบบ:เศษ ในฐานสิบเป็นทศนิยมรู้จบ (0.5) ในขณะที่ แม่แบบ:เศษ เป็นทศนิยมไม่รู้จบ (0.333…) จำนวนตรรกยะในฐานสองที่มีตัวส่วนเป็นกำลังของ 2 เท่านั้นที่เป็นทวินิยมรู้จบ (เช่น แม่แบบ:เศษ หรือ แม่แบบ:เศษ) จำนวนตรรกยะที่มีตัวส่วนเป็นตัวประกอบเฉพาะอื่นนอกจาก 2 เป็นทวินิยมไม่รู้จบ สิ่งนี้หมายความว่า จำนวนที่สั้นและแม่นยำซึ่งเขียนในฐานสิบ อาจจำเป็นต้องประมาณค่าเมื่อแปลงเป็นจำนวนจุดลอยตัวฐานสอง เช่น จำนวนฐานสิบ 0.1 ไม่สามารถแทนค่าได้อย่างแม่นยำในจำนวนจุดลอยตัวฐานสองอันมีความเที่ยงจำกัด การแทนฐานสองจะได้ลำดับ "1100" ซ้ำไปเรื่อย ๆ ไม่รู้จบ

e = −4; s = 1100110011001100110011001100110011…

เมื่อ s คือซิกนิฟิแคนด์และ e คือเลขชี้กำลัง ดังที่เคยอธิบายไว้ก่อนหน้า

เมื่อปัดเศษให้เหลือ 24 บิตจะกลายเป็น

e = −4; s = 110011001100110011001101

ซึ่งมีค่าที่แท้จริงเท่ากับ 0.100000001490116119384765625 ในฐานสิบ

หรืออีกตัวอย่างหนึ่ง จำนวนจริง π เขียนแทนในฐานสองด้วยลำดับบิตไม่รู้จบได้เป็น

11.0010010000111111011010101000100010000101101000110000100011010011…

เมื่อปัดเศษให้เหลือ 24 บิตจะกลายเป็น

11.0010010000111111011011

ในจำนวนจุดลอยตัวฐานสองแบบความเที่ยงหนึ่งเท่า จำนวนนี้จะแทนค่าด้วย s = 1.10010010000111111011011 และ e = 1 ซึ่งจำนวนนี้มีค่าในฐานสิบเป็น

3.1415927410125732421875

ในขณะที่การประมาณค่า π ที่เที่ยงตรงมากกว่าควรจะเป็น

3.1415926535897932384626433832795…

ผลลัพธ์ของการปัดเศษต่างจากค่าที่แท้จริงประมาณ 0.03 ส่วนต่อล้านส่วน และตรงกับเลขฐานสิบของ π เพียง 7 หลักแรก ส่วนต่างนี้เรียกว่าค่าคลาดเคลื่อนของความไม่ต่อเนื่อง (discretization error) และถูกจำกัดโดยเอปไซลอนเครื่องจักร (machine epsilon)

ผลต่างเชิงเลขคณิตระหว่างจำนวนจุดลอยตัวสองจำนวนที่สามารถแทนค่าได้และอยู่ติดกันตามลำดับ ซึ่งมีเลขชี้กำลังเดียวกัน ผลต่างนี้เรียกว่า หน่วยในตำแหน่งสุดท้าย (unit in the last place: ULP) ตัวอย่างเช่น ถ้าหากไม่มีจำนวนที่แทนค่าได้อยู่ระหว่าง 1.45a70c2216 กับ 1.45a70c2416 หน่วยในตำแหน่งสุดท้ายก็คือ 2×16−8 หรือเท่ากับ 2−31 สำหรับจำนวนที่มีเลขชี้กำลังเป็น 0 หน่วยในตำแหน่งสุดท้ายจะเท่ากับ 2−23 หรือประมาณ 10−7 ในความเที่ยงหนึ่งเท่า และประมาณ 10−16 ในความเที่ยงสองเท่า พฤติกรรมที่ถูกกำหนดของฮาร์ดแวร์ที่ยอมรับมาตรฐาน IEEE คือผลลัพธ์ต้องอยู่ภายในครึ่งหนึ่งของหน่วยในตำแหน่งสุดท้าย

วิธีการปัดเศษ

การปัดเศษจะถูกใช้เมื่อผลลัพธ์ที่ถูกต้องที่ได้จากการดำเนินการจำนวนจุดลอยตัว (หรือการแปลงเป็นรูปแบบจุดลอยตัว) มีเลขโดดมากเกินกว่าที่จะเก็บได้ในซิกนิฟิแคนด์ การปัดเศษมีวิธีการหลายแบบที่ต่างกัน แนวทางทั่วไปในอดีตคือการปัดเศษทิ้ง (truncation) และตั้งแต่มีการแนะนำ IEEE 754 แบบวิธีเริ่มต้นคือการปัดเศษเลขคู่ใกล้สุด หรือเรียกว่าการปัดเศษของนักธนาคาร (Banker's Rounding) มีใช้อย่างปกติสามัญมากกว่า แบบวิธีนี้จะปัดเศษผลลัพธ์ในอุดมคติ (ที่มีความเที่ยงอนันต์) จากการดำเนินการเลขคณิต ไปสู่จำนวนที่สามารถแทนค่าได้ที่ใกล้ที่สุด และให้ผลเป็นการแทนค่านั้นออกมา[note 1] ในกรณีที่ผลลัพธ์อยู่กึ่งกลาง ค่าที่มีซิกนิฟิแคนด์ลงท้ายเป็นเลขคู่จะถูกเลือก มาตรฐาน IEEE 754 กำหนดว่าจำเป็นต้องใช้วิธีการปัดเศษเดียวกันในทุก ๆ การดำเนินการพีชคณิตพื้นฐาน ซึ่งรวมถึงรากที่สองและการแปลงจำนวน เมื่อผลลัพธ์เป็นค่าเชิงตัวเลข สิ่งนี้หมายความว่า ผลลัพธ์จากการดำเนินการ IEEE 754 จะถูกพิจารณาทุกบิตในผลลัพธ์ ยกเว้นค่า NaN (ฟังก์ชัน "ไลบรารี" อาทิโคไซน์หรือลอการิทึมไม่ถูกบังคับ)

วิธีการปัดเศษทางเลือกอื่นก็มีให้ใช้ได้ IEEE 754 ได้ระบุวิธีการปัดเศษไว้ดังนี้

  • ปัดเศษสู่ค่าใกล้สุด ซึ่งค่าที่อยู่กึ่งกลางจะปัดเศษสู่เลขโดดที่เป็นเลขคู่ที่อยู่ใกล้สุดในตำแหน่งที่ต้องการ (วิธีการปริยายและปกติสามัญที่สุด)
  • ปัดเศษสู่ค่าใกล้สุด ซึ่งค่าที่อยู่กึ่งกลางจะปัดเศษในทิศทางออกจากศูนย์ (เป็นทางเลือกสำหรับจำนวนจุดลอยตัวฐานสอง และเป็นปกติสามัญในฐานสิบ)
  • ปัดเศษขึ้น (ในทิศทางเข้าสู่ +∞ ดังนั้นค่าลบจะปัดเศษเข้าหาศูนย์)
  • ปัดเศษลง (ในทิศทางเข้าสู่ −∞ ดังนั้นค่าลบจะปัดเศษออกจากศูนย์)
  • ปัดเศษเข้าหาศูนย์ (การปัดเศษทิ้ง คล้ายพฤติกรรมปกติในการแปลงจำนวนจุดลอยตัวเป็นจำนวนเต็ม เช่นจาก −3.9 เป็น −3)

แบบวิธีทางเลือกต่าง ๆ มีประโยชน์เมื่อจำนวนของค่าคลาดเคลื่อนต้องถูกจำกัดขอบเขต การประยุกต์ที่จำเป็นต้องใช้ค่าคลาดเคลื่อนที่จำกัดขอบเขต คือจำนวนจุดลอยตัวหลายความเที่ยง และเลขคณิตอันตรภาค (interval aritmetics)

การใช้งานการปัดเศษเพิ่มเติมคือ การปัดเศษจำนวนให้มีจำนวนหลักที่ต้องการในฐานสิบ (หรือฐานสอง) เช่นในการปัดเศษผลลัพธ์สกุลเงิน (จุดทศนิยมสองหลัก)

การดำเนินการเลขคณิตจุดลอยตัว

เพื่อความง่ายในการนำเสนอและการทำความเข้าใจ ตัวอย่างต่อไปนี้จะใช้เลขฐานสิบที่มีความเที่ยง 7 หลัก ตามที่ระบุไว้ใน IEEE 754 รูปแบบฐานสิบ 32 บิต หลักการพื้นฐานนั้นเหมือนกันในฐานหรือความเที่ยงใด ๆ เว้นแต่การทำให้เป็นบรรทัดฐานเป็นทางเลือกที่ไม่บังคับ (มันไม่ส่งผลต่อค่าเชิงจำนวนของผลลัพธ์) s ในที่นี้หมายถึงซิกนิฟิแคนด์และ e คือเลขชี้กำลัง

การบวกและการลบ

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

  123456.7 = 1.234567 × 10^5
  101.7654 = 1.017654 × 10^2 = 0.001017654 × 10^5
  ดังนั้น
  123456.7 + 101.7654 = (1.234567 × 10^5) + (1.017654 × 10^2)
                      = (1.234567 × 10^5) + (0.001017654 × 10^5)
                      = (1.234567 + 0.001017654) × 10^5
                      =  1.235584654 × 10^5

โดยรายละเอียด

  e=5;  s=1.234567     (123456.7)
+ e=2;  s=1.017654     (101.7654)
  e=5;  s=1.234567
+ e=5;  s=0.001017654  (หลังจากเลื่อนจุดฐานแล้ว)
--------------------
  e=5;  s=1.235584654  (ผลบวกแท้จริง 123558.4654)

ผลบวกนี้เป็นค่าแท้จริงที่ถูกต้องแม่นยำ มันจะถูกปัดเศษให้เหลือเพียงเจ็ดหลัก แล้วทำให้เป็นบรรทัดฐานหากจำเป็น ดังนั้นผลลัพธ์สุดท้ายคือ

  e=5;  s=1.235585    (ผลลัพธ์สุดท้าย 123558.5)

สังเกตว่าสามหลักสุดท้ายจากการบวก (654) สูญเสียไปอย่างสำคัญ สิ่งนี้เรียกว่าค่าคาดเคลื่อนการปัดเศษ (round-off error) ในกรณีสุดขีด ผลบวกของจำนวนสองจำนวนที่ไม่เป็นศูนย์อาจเท่ากับค่าเดิมของจำนวนใดจำนวนหนึ่ง

  e=5;  s=1.234567
+ e=-3; s=9.876543
  e=5;  s=1.234567
+ e=5;  s=0.00000009876543 (หลังจากเลื่อนจุดฐานแล้ว)
----------------------
  e=5;  s=1.23456709876543 (ผลบวกแท้จริง)
  e=5;  s=1.234567         (หลังจากปัดเศษ/ทำให้เป็นบรรทัดฐาน)

อีกตัวอย่างหนึ่งของปัญหาการสูญเสียนัยสำคัญ เกิดขึ้นในการลบสองจำนวนที่มีค่าใกล้เคียงกัน จากตัวอย่างนี้ แม่แบบ:Nowrap และ แม่แบบ:Nowrap เป็นการแทนค่าของจำนวนตรรกยะ 123457.1467 และ 123456.659 ตามลำดับ

  e=5;  s=1.234571
− e=5;  s=1.234567
----------------
  e=5;  s=0.000004
  e=−1; s=4.000000 (หลังจากปัดเศษ/ทำให้เป็นบรรทัดฐาน)

การแทนค่าที่ดีที่สุดของผลต่างนี้ควรเป็น แม่แบบ:Nowrap ซึ่งต่างจากผลลัพธ์ แม่แบบ:Nowrap อยู่มากกว่า 20% ในกรณีสุดขีด ผลลัพธ์สุดท้ายอาจกลายเป็นศูนย์แม้ว่าการคำนวณที่แท้จริงอาจได้ค่าหลายล้าน การสูญเสียนัยสำคัญเช่นนี้แสดงให้เห็นถึงความอันตรายในการสมมติว่า เลขโดดทุกหลักของผลลัพธ์ที่คำนวณได้ล้วนมีความหมาย การรับมือต่อผลสืบเนื่องของค่าคลาดเคลื่อนเหล่านี้เป็นหัวข้อศึกษาอันหนึ่งในการวิเคราะห์เชิงตัวเลข (numerical analysis) ดูเพิ่มที่ ปัญหาความแม่นยำ

การคูณและการหาร

การคูณกระทำได้โดยคูณซิกนิฟิแคนด์ทั้งสอง และบวกเลขชี้กำลังเข้าด้วยกัน ผลลัพธ์ที่ได้จะถูกปัดเศษและทำให้เป็นบรรทัดฐาน

  e=3;  s=4.734612
× e=5;  s=5.417242
-----------------------
  e=8;  s=25.648538980104 (ผลคูณแท้จริง)
  e=8;  s=25.64854        (หลังจากปัดเศษ)
  e=9;  s=2.564854        (หลังจากทำให้เป็นบรรทัดฐาน)

การหารก็กระทำด้วยวิธีที่คล้ายกันนี้ แต่ซับซ้อนมากกว่า

การคูณและการหารไม่เกิดปัญหาการสูญเสียหรือการดูดกลืนนัยสำคัญ แม้ว่าค่าคลาดเคลื่อนจำนวนน้อยอาจถูกสะสมในการดำเนินการที่กระทำซ้ำ ๆ[7] ในทางปฏิบัติ แนวทางของการดำเนินการเหล่านี้ค่อนข้างซับซ้อนในตรรกะดิจิทัล ดูที่ขั้นตอนวิธีการคูณของบูทและการหารเชิงดิจิทัล[note 2] สำหรับวิธีการที่รวดเร็วและง่าย ดูที่แบบแผนของฮอร์เนอร์

การรับมือกับกรณีผิดปรกติ

การคำนวณจำนวนจุดลอยตัวในคอมพิวเตอร์สามารถทำให้เกิดปัญหาสามประเภทได้แก่

  • การดำเนินการที่ไม่ถูกต้องในทางคณิตศาสตร์ เช่นการหารด้วยศูนย์
  • การดำเนินการที่ถูกต้องในหลักการ แต่ไม่รองรับโดยรูปแบบที่กำหนด ตัวอย่างเช่น การคำนวณรากที่สองของ −1 หรืออินเวิร์สไซน์ของ 2 (ทั้งสองให้ผลเป็นจำนวนเชิงซ้อน)
  • การดำเนินการที่ถูกต้องในหลักการ แต่ผลลัพธ์ที่ได้ไม่สามารถแทนค่าในรูปแบบที่กำหนดได้เลย เนื่องจากเลขชี้กำลังมีขนาดใหญ่หรือเล็กเกินกว่าที่จะเข้ารหัสลงในเขตข้อมูลเลขชี้กำลัง เหตุการณ์เช่นนี้มีทั้ง ภาวะมากเกินเก็บ (overflow เลขชี้กำลังใหญ่เกินไป) ภาวะน้อยเกินเก็บ (underflow เลขชี้กำลังเลขเกินไป) หรือการทำจำนวนให้ต่ำกว่าบรรทัดฐาน (denormalization สูญเสียความเที่ยง)

ก่อนที่จะมีมาตรฐาน IEEE เงื่อนไขดังกล่าวมักทำให้โปรแกรมหยุดทำงาน หรือกระตุ้นให้เกิดกับดัก (trap) ที่โปรแกรมเมอร์สามารถตรวจจับได้ แนวทางที่สิ่งนี้ทำงานขึ้นอยู่กับระบบ หมายความว่าโปรแกรมที่ใช้จำนวนจุดลอยตัวจะไม่สามารถย้ายไปทำงานบนเครื่องอื่นได้

มาตรฐานต้นฉบับ IEEE 754 (พ.ศ. 2527) เป็นก้าวแรกของวิธีการมาตรฐานสำหรับการดำเนินงานตาม IEEE 754 ในการบันทึกข้อผิดพลาดเกิดขึ้น ต่อไปนี้เราจะไม่พิจารณาการตรวจจับกับดัก (ซึ่งเป็นทางเลือกในรุ่น พ.ศ. 2527) และ "โหมดการจัดการสิ่งผิดปรกติแบบอื่น" (ซึ่งมาแทนที่การตรวจจับกับดักในรุ่น พ.ศ. 2551 แต่ก็ยังคงเป็นทางเลือก) แต่พิจารณาแค่แบบวิธีที่จำเป็นในการจัดการสิ่งผิดปรกติตาม IEEE 754 สิ่งผิดปรกติเชิงเลขคณิตต้องถูกบันทึกลงในบิตแสดงความผิดพลาดแบบ "ยึดติด" โดยปริยาย คำว่า "ยึดติด" หมายความว่า บิตแสดงความผิดพลาดจะไม่ถูกตั้งใหม่โดยการดำเนินการเลขคณิตถัดไป แต่จะยังคงมีค่าอยู่จนกว่าสั่งให้ตั้งใหม่อย่างแน่ชัด โดยปกติแล้วการดำเนินการหนึ่ง ๆ จะให้ผลลัพธ์ตามข้อกำหนดเสมอโดยไม่ยับยั้งการคำนวณ ตัวอย่างเช่น 1/0 ให้ผลลัพธ์เป็น +∞ พร้อมตั้งค่าบิตความผิดพลาดของการหารด้วยศูนย์ด้วย

อย่างไรก็ตามมาตรฐานต้นฉบับ IEEE 754 มิได้แนะนำการดำเนินการต่าง ๆ เพื่อจัดการกับกลุ่มของบิตความผิดพลาดเหล่านั้น ดังนั้นเมื่อสิ่งเหล่านี้ถูกพัฒนาในฮาร์ดแวร์ การทำให้เกิดผลจากภาษาโปรแกรมแต่เริ่มแรกจึงไม่ได้จัดเตรียมมาตรการเพื่อเข้าถึงมัน (นอกจากแอสเซมเบลอร์) ในเวลาต่อมามาตรฐานของภาษาโปรแกรมบางภาษา (เช่นภาษาซีหรือภาษาฟอร์แทรน) ได้ปรับปรุงเพื่อระบุแบบวิธีสำหรับเข้าถึงและเปลี่ยนแปลงสถานภาพกับบิตความผิดพลาด มาตรฐาน IEEE 754 รุ่น พ.ศ. 2551 ที่ใช้อยู่ในปัจจุบันจึงได้ระบุการดำเนินการบางชนิดสำหรับเข้าถึงและจัดการบิตความผิดพลาดเชิงเลขคณิต ตัวแบบการเขียนโปรแกรมที่มีพื้นฐานการทำงานเทร็ดเดียวแต่ถูกใช้โดยหลายเทร็ด จะต้องมีมาตรการเกี่ยวกับภาวะพร้อมกันนอกเหนือไปจากมาตรฐาน

IEEE 754 กำหนดความผิดพลาดเชิงเลขคณิตห้าประการที่ต้องถูกบันทึกในบิตความผิดพลาดที่ "ยึดติด" ดังนี้

  • ไม่แม่นยำ (inexact) บิตนี้จะถูกตั้งค่า ถ้าค่าที่ปัดเศษและส่งคืนจากการดำเนินการ ต่างจากผลลัพธ์แท้จริงในทางคณิตศาสตร์
  • น้อยเกินเก็บ (underflow) บิตนี้จะถูกตั้งค่า ถ้าค่าที่ปัดเศษมีขนาดเล็ก และ ไม่แม่นยำ ให้ผลเป็นค่าต่ำกว่าบรรทัดฐาน (รวมทั้งศูนย์ด้วย)
  • มากเกินเก็บ (overflow) บิตนี้จะถูกตั้งค่า ถ้าค่าสัมบูรณ์ของค่าที่ปัดเศษมีขนาดใหญ่เกินกว่าที่จะแทนได้ ค่าที่ส่งคืนอาจเป็นอนันต์หรือจำนวนมากสุดที่แทนค่าได้ ขึ้นอยู่กับวิธีการปัดเศษ
  • หารด้วยศูนย์ (divide-by-zero) บิตนี้จะถูกตั้งค่า ถ้าผลลัพธ์เป็นค่าไม่จำกัดอันเกิดจากตัวดำเนินการจำกัด ให้ค่าเป็น +∞ หรือ −∞ อย่างใดอย่างหนึ่ง
  • ไม่สมเหตุสมผล (invalid) บิตนี้จะถูกตั้งค่า ถ้าไม่สามารถคืนค่าผลลัพธ์จำนวนจริงได้อาทิ sqrt(−1) หรือ 0/0 จะคืนค่าเป็น quiet NaN แทน

ปัญหาความแม่นยำ

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

จากตัวอย่างต่อไปนี้ 0.1 และ 0.01 ในฐานสิบไม่สามารถแทนค่าได้ในฐานสองอย่างแม่นยำ หมายความว่าผลลัพธ์ของการพยายามคำนวณ 0.1 ยกกำลังสอง จะไม่ได้จำนวน 0.01 หรือจำนวนที่แทนค่าได้และใกล้เคียงที่สุดเลย ในการแทนค่า 24 บิต (ความเที่ยงหนึ่งเท่า) จำนวน 0.1 ฐานสิบ ดังที่เคยกล่าวไว้ว่าแทนค่าได้เป็น แม่แบบ:Nowrap มีค่าที่แท้จริงเท่ากับ

0.100000001490116119384765625

เมื่อนำจำนวนนี้มายกกำลังสองจะได้ผลลัพธ์แท้จริงเป็น

0.010000000298023226097399174250313080847263336181640625

หากนำมายกกำลังสองด้วยฮาร์ดแวร์จุดลอยตัวความเที่ยงหนึ่งเท่า (พร้อมทั้งปัดเศษ) จะได้

0.010000000707805156707763671875

แต่จำนวนที่แทนค่าได้และใกล้เคียง 0.01 ที่สุดคือ

0.009999999776482582092285156250

อีกตัวอย่างหนึ่ง จำนวนที่ไม่สามารถแทนค่าได้อย่าง π (และ π/2) ทำให้การพยายามคำนวณ tan(π/2) จะไม่ได้ผลลัพธ์เป็นค่าอนันต์หรือแม้แต่ภาวะมากเกินเก็บ ฮาร์ดแวร์คอมพิวเตอร์มาตรฐานไม่สามารถคำนวณ tan(π/2) เพราะ tan(π/2) ไม่สามารถแทนค่าได้อย่างแม่นยำ เช่นในการคำนวณในภาษาซีดังนี้

/* เลขโดดจำนวนมากเพื่อให้แน่ใจว่าการประมาณจะถูกต้อง */
double pi = 3.1415926535897932384626433832795;
double z = tan(pi/2.0);

จะให้ผลลัพธ์เป็น 16331239353195370.0 แต่ในความเที่ยงหนึ่งเท่า (ใช้ฟังก์ชัน tanf) ผลลัพธ์จะเป็น −22877332.0

ในกรณีคล้ายกัน การพยายามคำนวณ sin(π) จะไม่ได้ค่าศูนย์ ผลลัพธ์ที่ได้โดยประมาณจะเท่ากับ 0.1225แม่แบบ:E ในความเที่ยงสองเท่า หรือ −0.8742แม่แบบ:E ในความเที่ยงหนึ่งเท่า[note 3]

การบวกและการคูณจำนวนจุดลอยตัวมีสมบัติการสลับที่ (a + b = b + a และ a × b = b × a) แต่ไม่จำเป็นว่าจะต้องมีสมบัติการเปลี่ยนหมู่ นั่นคือ (a + b) + c ไม่จำเป็นต้องเท่ากับ a + (b + c) เสมอไป เช่นตัวอย่างต่อไปนี้เป็นเลขคณิตฐานสิบเจ็ดหลัก กำหนดให้ a = 1234.567, b = 45.67834, c = 0.0004

กรณี (a + b) + c

   1234.567   (a)
 +   45.67834 (b)
 ____________
   1280.24534  ปัดเศษเป็น  1280.245
   1280.245   (a + b)
 +    0.0004  (c)
 ____________
   1280.2454   ปัดเศษเป็น  1280.245

กรณี a + (b + c)

     45.67834 (b)
 +    0.0004  (c)
 ____________
     45.67874
     45.67874 (b + c)
 + 1234.567   (a)
 ____________
   1280.24574  ปัดเศษเป็น  1280.246

การบวกและการคูณจำนวนจุดลอยตัวก็ไม่จำเป็นต้องมีสมบัติการแจกแจง นั่นคือ (a + b) × c ไม่จำเป็นต้องเท่ากับ a × c + b × c เสมอไป จากตัวอย่างนี้กำหนดให้ a = 1234.567, b = 1.234567, c = 3.333333

กรณี (a + b) × c

 a + b = 1234.567 + 1.234567 = 1235.802
 
(a + b) × c
       = 1235.802 × 3.333333 = 4119.340

กรณี a × c + b × c

 a × c = 1234.567 × 3.333333 = 4115.223
 b × c = 1.234567 × 3.333333 = 4.115223
 a × c + b × c
       = 4115.223 + 4.115223 = 4119.338

นอกเหนือจากการสูญเสียนัยสำคัญ ความไม่สามารถในการแทนค่าจำนวนอาทิ π และ 0.1 ได้อย่างแม่นยำ และความไม่เที่ยงตรงเล็กน้อยอื่น ๆ ดังที่ได้กล่าวมาแล้ว ปรากฏการณ์ต่อไปนี้ก็อาจเกิดขึ้นได้เช่นกัน

  • การตัดออกหมด: การลบระหว่างตัวถูกดำเนินการที่มีค่าเกือบเท่ากันอาจทำให้สูญเสียความถูกต้องไปมาก สิ่งนี้อาจเป็นปัญหาความแม่นยำที่พบบ่อยและร้ายแรง
  • การแปลงเป็นจำนวนเต็มไม่เป็นไปตามที่คาด: เช่นการแปลง 63.0/9.0 เป็นจำนวนเต็มจะได้ 7 แต่การแปลง 0.63/0.09 อาจได้ 6 เนื่องจากการแปลงมักจะตัดเศษทิ้งมากกว่าปัดเศษ ฟังก์ชันพื้นและฟังก์ชันเพดานอาจให้คำตอบที่ต่างจากค่าคาดหวังอยู่หนึ่ง
  • พิสัยของเลขชี้กำลังจำกัด: ผลลัพธ์อาจล้นเกินเก็บทำให้เกิดอนันต์ หรือน้อยเกินเก็บทำให้เกิดจำนวนต่ำกว่าบรรทัดฐานหรือศูนย์ ในกรณีเหล่านี้ความเที่ยงจะสูญเสียไป
  • การทดสอบการหารที่ปลอดภัยเป็นปัญหา: การตรวจสอบว่าตัวหารไม่เป็นศูนย์ ไม่รับประกันได้ว่าผลหารจะไม่ล้นเกินเก็บ
  • การทดสอบภาวะเท่ากันเป็นปัญหา: ลำดับการคำนวณสองลำดับที่เท่ากันในเชิงคณิตศาสตร์ อาจให้ผลลัพธ์ต่างกันในจำนวนจุดลอยตัว บ่อยครั้งที่โปรแกรมเมอร์ทำการเปรียบเทียบภายในความคลาดเคลื่อนยินยอมบางค่า (มักจะเป็นค่าคงตัวฐานสิบ ซึ่งโดยตัวมันเองไม่สามารถแทนค่าได้อย่างแม่นยำ) แต่ก็ไม่จำเป็นว่าปัญหานี้จะหมดไป

ความเที่ยงของเครื่องจักร

"ความเที่ยงของเครื่องจักร" หมายถึงปริมาณที่บ่งบอกความแม่นยำของระบบจำนวนจุดลอยตัว เป็นที่รู้จักในชื่อ การปัดเศษหน่วย (unit round-off) หรือ เอปไซลอนเครื่องจักร (machine epsilon) มักจะแสดงด้วย Εmach ค่าของมันขึ้นอยู่กับวิธีการปัดเศษเฉพาะที่ใช้

การปัดเศษเข้าหาศูนย์จะได้

Emach=B1P

ในขณะที่การปัดเศษสู่ค่าที่ใกล้ที่สุดจะได้

Emach=12B1P

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

|fl(x)xx|Emach

การลดผลกระทบของปัญหาความแม่นยำ

การใช้เลขคณิตจำนวนจุดลอยตัวอย่างตรงไปตรงมา นำไปสู่ปัญหาหลายอย่างดังที่กล่าวมาแล้วทั้งหมดข้างต้น การสร้างซอฟต์แวร์จุดลอยตัวที่คงทนถาวรอย่างสมบูรณ์จึงเป็นงานที่ซับซ้อน และความเข้าใจอันดีของการวิเคราะห์เชิงตัวเลขเป็นสิ่งสำคัญ

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

เลขคณิตจุดลอยตัวฐานสอง เป็นสภาวการณ์ดีที่สุดเมื่อใช้วัดปริมาณในโลกแห่งความเป็นจริงซึ่งมีพิสัยของมาตราส่วนกว้าง (เช่นคาบดาราคติของไอโอหรือมวลของโปรตอน) แต่เป็นสภาวการณ์แย่ที่สุดเมื่อถูกคาดหวังให้จำลองความสัมพันธ์ของปริมาณในรูปของสายอักขระฐานสิบซึ่งมุ่งหวังว่าจะได้ค่าที่ถูกต้อง ตัวอย่างของกรณีหลังเช่นการคำนวณเชิงการเงิน ซอฟต์แวร์การเงินจึงมีความโน้มเอียงที่จะไม่ใช้การแทนจำนวนจุดลอยตัวฐานสองด้วยเหตุนี้[8] มาตรฐานจำนวนจุดลอยตัวฐานสิบของ IEEE 854 และชนิดตัวแปร "decimal" ของภาษาซีชาร์ปเป็นอาทิ ถูกออกแบบขึ้นเพื่อให้หลีกเลี่ยงปัญหาการแทนจำนวนจุดลอยตัวฐานสองที่ใช้กับค่าของเลขฐานสิบ ซึ่งมนุษย์จำเป็นต้องป้อนเข้าอย่างถูกต้อง และทำให้การคำนวณเลขคณิตได้ผลลัพธ์ตรงกับจำนวนฐานสิบที่คาดหวังเสมอ

ค่าคลาดเคลื่อนในเลขคณิตจุดลอยตัวอาจยิ่งสะสมมากขึ้น เมื่อขั้นตอนวิธีของการดำเนินการทางคณิตศาสตร์ถูกกระทำหลายครั้งมาก ตัวอย่างบางส่วนเช่น การหาตัวผกผันของเมทริกซ์ การคำนวณเวกเตอร์ลักษณะเฉพาะ และการแก้สมการเชิงอนุพันธ์ ขั้นตอนวิธีเหล่านี้จะต้องถูกออกแบบอย่างระมัดระวังมากเพื่อให้ทำงานได้ดี

ความคาดหวังต่าง ๆ ในทางคณิตศาสตร์อาจไม่สามารถทำให้เป็นจริงได้ในขอบเขตของการคำนวณจำนวนจุดลอยตัว ตัวอย่างเช่น เอกลักษณ์ทางคณิตศาสตร์อันเป็นที่ทราบโดยทั่วไปอาทิ (x+y)(xy)=x2y2 หรือ sin2θ+cos2θ=1 ไม่สามารถไว้วางใจได้เมื่อปริมาณที่เกี่ยวข้องเป็นผลลัพธ์มาจากการคำนวณจำนวนจุดลอยตัว

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

การทดสอบภาวะเท่ากัน (if (x==y) ...) โดยปกติไม่เป็นที่แนะนำเมื่อความคาดหวังขึ้นอยู่กับผลลัพธ์ทางคณิตศาสตร์ การทดสอบเช่นนี้บางครั้งถูกแทนที่ด้วยการเปรียบเทียบแบบ "คลุมเครือ" (if (abs(x-y) < epsilon) ... ซึ่ง epsilon มีค่าเล็กน้อยอย่างเพียงพอและถูกปรับให้เหมาะสมกับการใช้งานเช่น 1.0E−13) การตัดสินใจกระทำเช่นนี้แตกต่างหลากหลายอย่างมาก การจัดระเบียบรหัสดังกล่าวก็มักจะดีกว่าแม้การทดสอบดังกล่าวไม่มีความจำเป็น

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

3253.671
+  3.141276
--------
3256.812

สามหลักสุดท้ายของตัวบวกสูญเสียไปในผลลัพธ์ สมมติว่าเราต้องการบวกจำนวนหลายจำนวนซึ่งทุกจำนวนมีค่าประมาณ 3 หลังจากบวกเข้าไป 1000 ครั้ง ผลบวกจะเพิ่มขึ้นประมาณ 3000 เลขนัยสำคัญที่สูญไปมิได้ถูกนำกลับมาเพื่อคำนวณใหม่ ขั้นตอนวิธีการบวกของคาฮานอาจใช้เพื่อลดค่าคลาดเคลื่อนนี้ได้

การคำนวณอาจถูกปรับปรุงใหม่ในทางคณิตศาสตร์ที่เทียบเท่าแต่มีแนวโน้มของความคลาดเคลื่อนน้อยกว่า ตัวอย่างเช่น อาร์คิมิดีสประมาณค่า π โดยการคำนวณความยาวรอบรูปของรูปหลายเหลี่ยมที่บรรจุภายในและภายนอกรูปวงกลม โดยเริ่มที่รูปหกเหลี่ยมแล้วเพิ่มจำนวนด้านทีละสองเท่า สูตรเวียนเกิดของรูปหลายเหลี่ยมภายนอกรูปวงกลมคือ

t0=13
รูปแบบที่หนึ่ง: ti+1=ti2+11ti; รูปแบบที่สอง: ti+1=titi2+1+1
π6×2i×ti ลู่เข้าเมื่อ i

ในที่นี้จะคำนวณด้วยเลขคณิต "double" แบบ IEEE (ซิกนิฟิแคนด์ที่มีความเที่ยง 53 บิต)

 i   6 × 2i × ti รูปแบบที่หนึ่ง       6 × 2i × ti รูปแบบที่สอง
  
 0   แม่แบบ:สี.4641016151377543863      แม่แบบ:สี.4641016151377543863
 1   แม่แบบ:สี.2153903091734710173      แม่แบบ:สี.2153903091734723496
 2   แม่แบบ:สี596599420974940120      แม่แบบ:สี596599420975006733
 3   แม่แบบ:สี60862151314012979      แม่แบบ:สี60862151314352708
 4   แม่แบบ:สี27145996453136334      แม่แบบ:สี27145996453689225
 5   แม่แบบ:สี8730499801259536      แม่แบบ:สี8730499798241950
 6   แม่แบบ:สี6627470548084133      แม่แบบ:สี6627470568494473
 7   แม่แบบ:สี6101765997805905      แม่แบบ:สี6101766046906629
 8   แม่แบบ:สี70343230776862      แม่แบบ:สี70343215275928
 9   แม่แบบ:สี37488171150615      แม่แบบ:สี37487713536668
10   แม่แบบ:สี9278733740748      แม่แบบ:สี9273850979885
11   แม่แบบ:สี7256228504127      แม่แบบ:สี7220386148377
12   แม่แบบ:สี717412858693      แม่แบบ:สี707019992125
13   แม่แบบ:สี189011456060      แม่แบบ:สี78678454728
14   แม่แบบ:สี717412858693      แม่แบบ:สี46593073709
15   แม่แบบ:สี19358822321783      แม่แบบ:สี8571730119
16   แม่แบบ:สี717412858693      แม่แบบ:สี6566394222
17   แม่แบบ:สี810075796233302      แม่แบบ:สี6065061913
18   แม่แบบ:สี717412858693      แม่แบบ:สี939728836
19   แม่แบบ:สี4061547378810956      แม่แบบ:สี908393901
20   แม่แบบ:สี05434924008406305      แม่แบบ:สี900560168
21   แม่แบบ:สี00068646912273617      แม่แบบ:สี8608396
22   แม่แบบ:สี349453756585929919      แม่แบบ:สี8122118
23   แม่แบบ:สี00068646912273617      แม่แบบ:สี95552
24   แม่แบบ:สี.2245152435345525443      แม่แบบ:สี68907
25                              แม่แบบ:สี62246
26                              แม่แบบ:สี62246
27                              แม่แบบ:สี62246
28                              แม่แบบ:สี62246
               ค่าที่แท้จริงคือ แม่แบบ:สี

ในขณะที่รูปแบบทั้งสองของสูตรเวียนเกิดเทียบเท่ากันอย่างชัดเจน สูตรแรกมีการลบ 1 ด้วยจำนวนที่มีค่าใกล้เคียง 1 อย่างสุดขีด จนทำให้เกิดการตัดออกหมดขนานใหญ่ สังเกตว่าการเวียนเกิดซ้ำ ๆ จะให้ผลที่แม่นยำมากขึ้นในตอนแรก แต่ภายหลังก็ลดลง ไม่สามารถมีค่าที่แม่นยำมากกว่า 8 หลัก แม้จะใช้เลขคณิต 53 บิตที่สามารถจัดการกับความเที่ยงประมาณ 16 หลัก ในอีกทางหนึ่ง สูตรที่สองของการเวียนเกิดให้ผลลัพธ์ลู่เข้าที่แม่นยำถึง 15 หลัก

เชิงอรรถ

  1. ฮาร์ดแวร์คอมพิวเตอร์ไม่จำเป็นต้องคำนวณแล้วได้ค่าที่ถูกต้องแม่นยำ มันเพียงต้องสร้างผลลัพธ์ที่เทียบเท่ากันซึ่งปัดเศษแล้ว แม้ว่าผลที่คำนวณได้เป็นผลลัพธ์ที่มีความเที่ยงอนันต์
  2. ความซับซ้อนอย่างมหาศาลของขั้นตอนวิธีการหารสมัยใหม่ครั้งหนึ่ง นำมาซึ่งความผิดพลาดอันโด่งดัง ชิปอินเทล เพนเทียม รุ่นแรก ๆ มาพร้อมกับชุดคำสั่งการหารที่ให้ผลลัพธ์ไม่ถูกต้องเล็กน้อย แต่ก็มีโอกาสเกิดขึ้นได้ยาก คอมพิวเตอร์จำนวนมากขายออกไปก่อนที่จะค้นพบความผิดพลาดนี้ มีการพัฒนาคอมไพเลอร์รุ่นซ่อมแซมหลายรุ่นเพื่อให้สามารถหลีกเลี่ยงกรณีที่ผิดพลาด จนกระทั่งคอมพิวเตอร์ที่บกพร่องทั้งหลายถูกเปลี่ยนแทนที่ ดูรายละเอียดได้ที่ บั๊ก FDIV ของเพนเทียม
  3. แต่การพยายามคำนวณ cos(π) จะได้ค่า −1 อย่างแม่นยำ เนื่องจากอนุพันธ์ของฟังก์ชัน cos จะมีค่าเข้าใกล้ศูนย์ เมื่ออาร์กิวเมนต์มีค่าเข้าใกล้ π ความไม่แม่นยำของอาร์กิวเมนต์มีผลกระทบเล็กน้อยมากเมื่อเทียบกับช่องว่างจำนวนจุดลอยตัวทางซ้ายและทางขวาของค่า −1 หลังจากปัดเศษแล้วผลลัพธ์จึงแม่นยำ

อ้างอิง

แม่แบบ:รายการอ้างอิง

แหล่งข้อมูลอื่น

  • Kahan, William and Darcy, Joseph (2001). How Java’s floating-point hurts everyone everywhere. Retrieved September 5, 2003 from http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf.
  • The pitfalls of verifying floating-point computations, by David Monniaux, also printed in ACM Transactions on programming languages and systems (TOPLAS), May 2008: a compendium of non-intuitive behaviours of floating-point on popular architectures, with implications for program verification and testing
  • Survey of Floating-Point Formats บทสรุปอย่างสั้นของรูปแบบจำนวนจุดลอยตัวที่เคยมีใช้ในอดีต

หนังสืออ่านเพิ่มเติม