(ทำให้เสร็จสมบูรณ์) บทช่วยสอนเพื่อการทำความเข้าใจเกี่ยวกับข้อผิดพลาดข้อมูลเลขทศนิยมของ IEEE

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

ต่อไปนี้เป็นฉบับภาษาอังกฤษของบทความนี้:42980
การปฏิเสธความรับผิดชอบในเนื้อหาของ KB ที่จะไม่มีการปรับปรุงอีกต่อไป
บทความนี้กล่าวถึงผลิตภัณฑ์ที่ Microsoft ไม่มีการสนับสนุนอีกต่อไป เนื้อหาของบทความจึงมีการนำเสนอ "ตามลักษณะที่เป็น" และจะไม่มีการปรับปรุงข้อมูลอีก
สรุป
คณิตศาสตร์ทศนิยมคือ หัวข้อซับซ้อนที่ confuses มากโปรแกรมเมอร์ บทช่วยสอนเกี่ยวกับด้านล่างนี้จะช่วยให้คุณจดจำการเขียนโปรแกรมสถานการณ์ที่มักจะเกิดข้อผิดพลาดข้อมูลเลขทศนิยมที่มี และวิธีการหลีกเลี่ยงการเหล่านั้น ดังกล่าวควรยังให้คุณสามารถใช้กรณีที่เป็นที่รู้จักสาเหตุมาจากข้อจำกัดทางคณิตศาสตร์ floating-point ลำดับชั้นเป็นกันไปบักคอมไพเลอร์ที่แท้จริง
ข้อมูลเพิ่มเติม

ระบบของเลขฐานสิบ และไบนารี

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

หมายเลข 532.25 เป็นเลขฐานสิบ (ฐาน 10) หมายความ ต่อไปนี้:
   (5 * 10^2) + (3 * 10^1) + (2 * 10^0) + (2 * 10^-1) + (5 * 10^-2)       500    +     30     +      2     +     2/10    +    5/100   _________   =  532.25				

ในระบบการเลขไบนารี (ฐาน 2), แต่ละคอลัมน์แทนการใช้พลังงาน2 แทนที่เป็น 10 ตัวอย่างเช่น หมายเลข 101.01 หมายถึงการต่อไปนี้:
   (1 * 2^2) + (0 * 2^1) + (1 * 2^0) + (0 * 2^-1) + (1 * 2^-2)       4     +      0    +     1     +      0     +    1/4   _________   =  5.25  Decimal				

วิธีแสดงเป็นจำนวนเต็มในพีซี

เนื่องจากไม่มีเศษส่วนเป็นจำนวนเต็ม ของเครื่องจักรการแสดงจะง่ายกว่ามากมากกว่าความสำหรับค่าข้อมูลเลขทศนิยม ปกติจำนวนเต็มที่อยู่บนเครื่องคอมพิวเตอร์ส่วนบุคคล (พีซี) เป็น 2 ไบต์ (16 บิต) ยาวมีการบิตที่มีนัยสำคัญมากที่สุดเพื่อแสดงเครื่องหมาย จำนวนเต็มแบบยาวมีความยาว 4 ไบต์ค่าบวกเป็นตัวเลขไบนารีที่ตรง ตัวอย่าง:
    1 Decimal = 1 Binary    2 Decimal = 10 Binary   22 Decimal = 10110 Binary, etc.				

อย่างไรก็ตาม จำนวนเต็มที่เป็นค่าลบจะแสดงโดยใช้สองของส่วนเติมเต็มโครงร่าง เมื่อต้องรับสองของส่วนเติมเต็มแทนสำหรับค่าลบหมายเลข ใช้เวลาที่แสดงไบนารีสำหรับค่าสัมบูรณ์ของจำนวนแล้วพลิกบิตทั้งหมด และเพิ่ม 1 ครั้ง ตัวอย่าง:
   4 Decimal = 0000 0000 0000 0100               1111 1111 1111 1011     Flip the Bits   -4        = 1111 1111 1111 1100     Add 1				

โปรดสังเกตว่า -1 เลขฐานสิบ = 1111 1111 1111 1111 ในไบนารี ซึ่งอธิบายสาเหตุที่ Basic ถือว่า -1 เป็นตรรกะ true (บิตทั้งหมด = 1) นี่คือคำซึ่งไม่มีตัวดำเนินการแยกต่างหากสำหรับ bitwise และแบบลอจิคัลเปรียบเทียบ บ่อยครั้งใน Basic จะสะดวกในการใช้โค้ดด้านล่างนี้เมื่อโปรแกรมของคุณจะสามารถทำการเปรียบเทียบแบบลอจิคัลหลายครั้ง นี้ช่วยอ่านได้อย่างมากขึ้น
   CONST TRUE = -1   CONST FALSE = NOT TRUE				

หมายเหตุที่เพิ่มได้ทั้งสองของส่วนเติมเต็มเลขเข้าด้วยกันใช้เลขคณิตฐานสองธรรมดาก่อให้เกิดผลลัพธ์ถูกต้อง

ข้อมูลเลขทศนิยมนั้น

ทุกจำนวนเต็มฐานสิบสามารถถูกแสดงอย่างแน่นอน ด้วยเป็นจำนวนเต็มฐานสองอย่างไรก็ตาม นี้ไม่จริงสำหรับตัวเลขที่เป็นเศษส่วน แท้ที่จริง ทุก ๆคุณยังสามารถ irrational ในหมายเลขที่ irrational ในฐาน 10ระบบ มีขนาดเล็กกว่า 10 ฐาน

สำหรับไบนารี ตัวเลขเฉพาะ เป็นบางส่วนเท่านั้นที่สามารถแสดงในแบบฟอร์มของ p/q, q ซึ่งเป็นการใช้พลังงานเป็นจำนวนเต็มของ 2 สามารถแสดงทุกประการ ด้วยบิตจำนวนจำกัด

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

นี้อธิบายถึงสาเหตุที่ตัวอย่างง่าย ๆ ต่อไปนี้
   SUM = 0   FOR I% = 1 TO 10000      SUM = SUM + 0.0001   NEXT I%   PRINT SUM                   ' Theoretically = 1.0.				

จะพิมพ์ 1.000054 เป็นผลผลิต ข้อผิดพลาดเล็กน้อยในการแสดงถึง 0.0001ในแบบไบนารีแพร่กระจายผลรวม

ด้วยเหตุผลเดียวกัน คุณเสมอควรระมัดระวังให้มากเมื่อทำการการเปรียบเทียบในระบบจำนวนจริง ตัวอย่างต่อไปนี้แสดงให้เห็นเป็นผิดพลาดทั่วไปเขียนโปรแกรม:
   item1# = 69.82#   item2# = 69.20# + 0.62#   IF item1# = item2# then print "Equality!"				

ซึ่งจะพิมพ์ "พจน์เนื่องจากไม่สามารถแสดง 69.82 ได้แน่นอนในไบนารี ซึ่งทำให้ค่าที่เป็นผลลัพธ์จากการกำหนด (ในไบนารี) แตกต่างไปเล็กน้อยกว่าค่าที่สร้างขึ้นจากนิพจน์ ในแบบฝึกหัด คุณเสมอควรรหัสการเปรียบเทียบดังกล่าวในลักษณะเป็นการอนุญาตให้ใช้ค่าเผื่อในการทำงานบางอย่าง สำหรับตัวอย่าง:
   IF (item1# < 69.83#) AND (item1# > 69.81#) then print "Equal"				

ซึ่งจะพิมพ์ "เท่ากับ"

หมายเลขการจัดรูปแบบ IEEE

QuickBasic สำหรับ MS-DOS เวอร์ชั่น 3.0 ถูกจัดส่ง ด้วยการ MBFเวอร์ชั่น (Microsoft ไบนารี Floating จุด) และมี IEEE (Institute ของรุ่นที่ใช้ไฟฟ้าและอุปกรณ์อิเล็กทรอนิกส์วิศวกร) สำหรับเครื่องจักรที่มีการcoprocessor คณิตศาสตร์ QuickBasic สำหรับ MS-DOS เวอร์ชั่น 4.0 และรุ่นที่ใหม่กว่าใช้ IEEE เท่า นั้น Microsoft ได้เลือกมาตรฐาน IEEE เพื่อแทนค่าทศนิยมในเวอร์ชันปัจจุบันของ Basic สำหรับต่อไปนี้เหตุผลหลักสาม:
  1. เมื่อต้องอนุญาต Basic เมื่อต้องใช้ที่ Intel คณิตศาสตร์ coprocessors ซึ่งใช้ IEEE รูปแบบ Coprocessors ชุด Intel 80 x 87 ที่ไม่สามารถทำงานกับ หมายเลขของรูปแบบไบนารีของ Microsoft
  2. เมื่อต้องการทำให้ interlanguage เรียกระหว่าง Basic, C, Pascal, FORTRAN และ MASM ง่ายยิ่งขึ้น มิฉะนั้น งานประจำเกี่ยวกับการแปลงจะมีการ ใช้เพื่อส่งค่าตัวเลขจากภาษาหนึ่งไปยังอีก
  3. เมื่อต้องบรรลุความสอดคล้องกัน IEEE เป็นมาตรฐานสำหรับอุตสาหกรรมยอมรับ Compilers C และ FORTRAN
ต่อไปนี้เป็นการเปรียบเทียบอย่างรวดเร็วของ IEEE และ MBF ที่ใช้แทนสำหรับตัวเลขความแม่นยำสอง:
               Sign Bits   Exponent Bits   Mantissa Bits               ---------   -------------   -------------   IEEE        1           11              52 + 1 (Implied)    MBF        1            8              56				

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับความแตกต่างระหว่าง IEEE และ MBFการแสดงข้อมูลเลขทศนิยม แบบสอบถามใน Microsoft Knowledge Base บนคำต่อไปนี้:
   IEEE and floating and point and appnote				

โปรดสังเกตว่า IEEE มีบิตที่กำหนดให้ใช้เลขชี้กำลัง ซึ่งช่วยให้เพิ่มเติมอีเมลไปแทนช่วงกว้างของค่า MBF มีบิต mantissa เพิ่มเติมซึ่งช่วยให้ชัดเจนยิ่งขึ้นภายในช่วงนั้นให้แคบลงให้

แนวคิดทั่วไปเกี่ยวกับข้อมูลเลขทศนิยม

จำเป็นอย่างยิ่งสำหรับที่การทำให้ระบบทศนิยมใด ๆ ก็ตามไบนารีสามารถแสดงจำนวนค่าข้อมูลเลขทศนิยมในข้อความที่แน่นอนจำกัดเท่านั้นแบบฟอร์ม ต้องหาค่าประมาณค่าอื่น ๆ ทั้งหมด โดยใกล้เคียงที่สุดค่าของ representable มาตรฐาน IEEE ระบุวิธีการสำหรับปัดค่าให้เป็นค่า representable "ใกล้เคียงที่สุด" QuickBasicสนับสนุนมาตรฐานสำหรับ MS-DOS และปัดเศษตาม IEEEกฎ

นอกจากนี้ สนใจเก็บไว้ในที่หมายเลขที่สามารถแสดงได้ใน IEEEกำลังแพร่กระจายออกไปในช่วงที่กว้างมาก คุณสามารถจินตนาการในการหมายเลขบรรทัด ไม่มีความหนาแน่นของสูงของตัวเลข representable ใกล้ 1.0และ -1.0 แต่น้อยกว่า และน้อยกว่าในขณะที่คุณไปจนถึง 0 หรือจำนวนอนันต์

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

รายละเอียดของ IEEE

ตัวเลขทศนิยมจะแสดงในแบบฟอร์มต่อไปนี้ ซึ่ง[เลขชี้กำลัง] เป็นไบนารีเลขชี้กำลัง:
   X =  Fraction * 2^(exponent - bias)				

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

[ความโน้มเอียงของ] คือ ค่า bias ที่ใช้เพื่อหลีกเลี่ยงการจัดเก็บเป็นค่าลบเลขชี้กำลัง

ความโน้มเอียงของการสำหรับหมายเลขเดียวความแม่นยำคือ 127 และ 1023 (ฐานสิบ) สำหรับหมายเลขความแม่นยำสองครั้ง

ค่าเท่ากับ 0 ทั้งหมด และมีจองสำหรับ 1 ทั้งหมด (ไบนารี)แสดงกรณีพิเศษ มีกรณีพิเศษอื่น ๆ ด้วยที่บ่งชี้เงื่อนไขข้อผิดพลาดต่าง ๆ

ตัวอย่างเดียวของความแม่นยำ

2 = 1 * 2 ^ 1 = 0100 0000 0000 ของ 0000 ... 0000 0000 = 4000 0000 hex
หมายเหตุบิตเครื่องหมายเป็นศูนย์ และเลขชี้กำลังเก็บไว้คือ 128 หรือ 100 0000 0 ในไบนารี ซึ่งคือ 127 บวก 1 Mantissa เก็บไว้เป็น (1) 000 0000 ... 0000 0000 ซึ่งมี 1 เป็นการนำโดยนัย และ ไบนารีจุด ดังนั้น mantissa แท้จริงเป็น 1

-2 = -1 * 2 ^ 1 = 1100 0000 0000 ของ 0000 ... 0000 0000 = C000 0000 hex
เหมือน +2 เว้นเสียแต่ว่ามีการตั้งค่าบิตเครื่องหมาย นี้เป็นจริงสำหรับทั้งหมด IEEE รูปแบบเลขทศนิยม

4 = 1 * 2 ^ 2 = 0100 0000 การ 1000 0000 ... ฐานสิบหก 0000 0000 = 4080 ของ 0000
Mantissa เดียวกัน เลขชี้กำลังที่เพิ่มขึ้นทีละหนึ่ง (ค่า biased เป็น 129 หรือ 1 0000 100 ในไบนารี

6 = 1.5 * 2 ^ 2 = 0100 0000 การ 1100 0000 ... 0000 0000 = 40C 0 0000 ฐานสิบหก
เดียวกันกับเลขชี้กำลัง mantissa มีขนาดใหญ่ โดยครึ่ง--เป็น (1) 100 0000 ... 0000 0000 ใด เนื่องจากเป็นไบนารี เศษส่วน คือ 1-1/2 (ค่าต่าง ๆ ของตัวเลขเป็นเศษส่วนคือ 1/2 1/4, 1/8 ฯลฯ)

1 = 1 * 2 ^ 0 = 0011 0000 1000 ของ 1111 ... 0000 0000 = 3F80 0000 hex
เดียวกัน exponent เป็นเลขยกกำลังอื่น ๆ ของ 2, mantissa เป็นแถบเครื่องมือน้อยกว่า 2 ที่ 127 หรือ 1 1111 011 ในไบนารี

.75 = 1.5 * 2 ^ -1 = 0011 1111 0100 0000 ... 0000 0000 = 3F40 0000 hex
เลขชี้กำลัง biased คือ 126, 011 1111 0 ในไบนารี mantissa และ คือ (1) 100 0000 ... 0000 0000 ซึ่งเป็น 1-1/2

1.25 * 2.5 = 2 ^ 1 = 0100 0000 การ 0010 0000 ... ฐานสิบหก 0000 0000 = 4020 ของ 0000
บิตซึ่งแสดงถึง 1/4 มีแน่นอนเหมือนยกเว้นที่ 2 ตั้งค่าในแบบ mantissa

0.1 = 1.6 * 2 ^ -4 = 0011 1101 1100 1100 ... 1100 1101 =ฐานสิบหกของ CCCD 3DCC
1/10 เป็นเศษส่วนซ้ำในไบนารี Mantissa มีเพียงแค่ shy ของ 1.6 และข้อความว่า เลขชี้กำลัง biased ว่า 1.6 จะถูกหารด้วย 16 (นั้นคือ 1 1101 011 ในไบนารี ซึ่งเป็น 123 เป็นเลขฐานสิบ) จริง เลขชี้กำลังคือ 123-127 = - 4 ซึ่งหมายความ ว่า ตัวสุดท้าย เมื่อต้องคูณคือ 2 ** -4 = 1/16 โปรดสังเกตว่า mantissa เก็บไว้ ปัดเศษในบิตการล่าสุด นี่คือความพยายามในการแทน unrepresentable ถูกต้องที่เป็นไปได้ที่หมายเลข (เหตุผลที่ 1/10 และ 1/100 จะ representable ไม่แน่นอนในไบนารีคล้ายกัน ในวิธี ที่ 1/3 จะยังไม่ถูกต้อง representable เป็นเลขฐานสิบ)

0 = 1.0 * 2 ^ -128 =เลขศูนย์ทั้งหมด - กรณีพิเศษ

ข้อผิดพลาดข้อมูลเลขทศนิยมอื่น ๆ ทั่วไป

ต่อไปนี้เป็นข้อผิดพลาดทั่วไปที่ข้อมูลเลขทศนิยม:
  1. ปัดเศษข้อผิดพลาด

    ข้อผิดพลาดนี้เกิดเมื่อบิตในตัวเลขฐานสองทั้งหมดไม่สามารถ สามารถใช้ในการคำนวณ

    ตัวอย่าง: เพิ่ม 0.0001 เมื่อต้องการ 0.9900 (ความแม่นยำเดียว)

    การแสดงทศนิยม 0.0001 เป็น:
    (1) 10100011011011100010111 * 2^(-14+Bias) (13 นำ 0 s ใน ไบนารี)
    0.9900 จะแสดงในรูปของ:
    (1) 11111010111000010100011 * 2^(-1+Bias)
    ตอนนี้ เมื่อต้องการจริง ๆ แล้ว เพิ่มตัวเลขเหล่านี้ จุดทศนิยม (ไบนารี) ต้อง จัดวางตำแหน่ง สำหรับสิ่งนี้ จะต้องเป็น Unnormalized ต่อไปนี้คือการ หากต้องการเพิ่มผลลัพธ์ที่ได้:
           .000000000000011010001101 * 2^0  <- Only 11 of 23 Bits retained      +.111111010111000010100011 * 2^0      ________________________________       .111111010111011100110000 * 2^0						
    ลักษณะนี้เรียกว่าผิดพลาดการปัดเศษเนื่องจากการปัดเศษเมื่อคอมพิวเตอร์บางเครื่อง เลื่อนสำหรับการบวก ผู้อื่นเพียงแค่ตัดกัน มีการปัดเศษข้อผิดพลาด สิ่งสำคัญที่ควรพิจารณาเมื่อใดก็ตามคุณกำลังเพิ่ม หรือคูณสอง ค่าที่แตกต่างกันมากขึ้น
  2. Subtracting สองเกือบเท่ากับค่า
           .1235      -.1234       _____       .0001						
    จะเป็นปกติครั้งนี้ โปรดสังเกตว่า แม้ว่าหมายเลขต้นฉบับ แต่ละมีนัยสำคัญสี่ ผลลัพธ์ได้อย่างใดอย่างหนึ่งเท่านั้น ตัวเลขที่มีนัยสำคัญ
  3. มากเกินไปและน้อยเกินไป

    เหตุการณ์นี้เกิดขึ้นเมื่อผลลัพธ์มีขนาดใหญ่เกินไป หรือเล็กเกินไปให้ แสดง โดยชนิดข้อมูล
  4. ข้อผิดพลาด quantizing

    เกิดปัญหานี้ขึ้นกับหมายเลขดังกล่าวไม่สามารถแสดงในข้อความที่แน่นอน แบบฟอร์มตามมาตรฐานข้อมูลเลขทศนิยม
  5. หาร ด้วยตัวเลขขนาดเล็กมาก

    ซึ่งสามารถก่อให้เกิดข้อผิดพลาด "การหาร ด้วยศูนย์" หรือสามารถสร้าง bad ผลลัพธ์ ตามตัวอย่างต่อไปนี้:
          A = 112000000      B = 100000      C = 0.0009      X = A - B / C						
    ใน QuickBasic สำหรับ MS-DOS, X ในตอนนี้มีค่า 888887 แทน คำตอบถูก 900000
  6. ข้อผิดพลาดในการแสดงผล

    ชนิดของข้อผิดพลาดนี้เกิดขึ้นเมื่อฟังก์ชันการแสดงผลมีการเปลี่ยนแปลง ค่าที่ทำงานด้วย
1.00 2.00 3.00 4.00 4.00b 4.50 6.00 6.00b IEEETUTR 7.00 7.10

คำเตือน: บทความนี้ได้รับการแปลโดยอัตโนมัติ

คุณสมบัติ

รหัสบทความ: 42980 - การตรวจสอบครั้งสุดท้าย: 10/30/2012 02:53:00 - ฉบับแก้ไข: 4.0

Microsoft Visual Basic 2.0 Standard Edition, Microsoft Visual Basic 3.0 Professional Edition, Microsoft Visual Basic 1.0 Standard Edition, Microsoft Visual Basic 2.0 Professional Edition, Microsoft BASIC Professional Development System 7.0

  • kbmt KB42980 KbMtth
คำติชม