(पूर्ण) IEEE फ़्लोटिंग पॉइंट त्रुटियों को समझने के लिए ट्यूटोरियल

रिटायर्ड KB सामग्री अस्वीकरण

यह आलेख उन उत्पादों के बारे में लिखा गया था जिनके लिए अब Microsoft समर्थन प्रदान नहीं करता है . इसलिए, यह आलेख "जैसा है" वैसा ही ऑफ़र किया गया है और अब इसका अद्यतन नहीं किया जाएगा.

सारांश

फ़्लोटिंग पॉइंट गणित confuses कई प्रोग्रामर एक जटिल विषय है। नीचे ट्यूटोरियल प्रोग्रामिंग स्थितियों जहाँ त्रुटियाँ फ़्लोटिंग पॉइंट होने की संभावना है और उन्हें से बचने के लिए कैसे पहचानें आपकी मदद चाहिए। यह भी वास्तविक कंपाइलर बग्स विपरीत फ़्लोटिंग पॉइंट गणित inherent सीमाओं के कारण होते हैं जो मामले की पहचान करने की अनुमति होना चाहिए।

अधिक जानकारी

दशमलव और बाइनरी संख्या सिस्टम्स

सामान्य रूप से, हम बातें मूल 10 में गिने जाते हैं। बेस पूरी तरह हो गई है। उनके पास 10 उंगलियाँ जो गणना उपकरण उपलब्ध किए गए हैं, लोग traditionally बेस 10 का उपयोग किया है कि केवल कारण है।


दशमलव (आधार 10) की संख्या 532.25 निम्न अर्थ है:

   (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), किसी पावर 10 के स्थान पर 2 का प्रतिनिधित्व करता है। उदाहरण के लिए, संख्या 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


पूर्णांकों पीसी में कैसे प्रस्तुत किए

क्योंकि कोई भिन्नात्मक भाग एक पूर्णांक नहीं है, उसकी मशीन प्रतिनिधित्व फ़्लोटिंग पॉइंट मान के लिए है काफी सरल है। सामान्य अंकों को पर्सनल कंप्यूटर (Pc) पर 2 बाइट्स (16 बिट) चिह्न इंगित करता है लंबे समय तक सर्वाधिक महत्वपूर्ण बिट के साथ हैं। लंबा पूर्णांकों 4 बाइट्स की लंबाई है। Straightforward बाइनरी संख्या धनात्मक मान हैं। उदाहरण के लिए:

    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 के रूप में तार्किक सही मानता (सभी बिट्स = 1)। Consequence और bitwise तार्किक तुलना के लिए अलग-अलग ऑपरेटर नहीं होने का है। प्राय: मूल में, यह कई तार्किक तुलना अपने प्रोग्राम कर दिया जाएगा जब नीचे कोड अंश का उपयोग करने के लिए सुविधाजनक है। यह बहुत अधिक पठनीयता ऐड्स।

   CONST TRUE = -1
CONST FALSE = NOT TRUE


जोड़ने के किसी भी संयोजन के दो की संख्या साधारण बाइनरी समांतर का उपयोग करते हुए एक साथ पूरा नोट सही परिणाम देती है।

फ़्लोटिंग पॉइंट Complications

प्रत्येक दशमलव पूर्णांक निश्चित रूप से एक बाइनरी पूर्णांक द्वारा प्रस्तुत किया जा सकता; हालांकि, यह भिन्नात्मक संख्याओं के लिए सही नहीं है। वास्तव में, प्रत्येक में मूल 10 irrational संख्या भी 10 से छोटे आधार के साथ किसी भी सिस्टम में irrational होंगे।


बाइनरी के लिए, विशेष रूप से, प्रपत्र p/एक पूर्णांक घात 2 जहाँ q है, q में, प्रस्तुत किया जा सकता केवल भिन्नात्मक संख्याओं निश्चित रूप से, बिट्स की एक सीमित संख्या के साथ व्यक्त किया जा कर सकते हैं।


यहाँ तक कि सामान्य दशमलव भिन्न, दशमलव 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 (इंस्टिट्यूट की विद्युत और इलेक्ट्रॉनिक्स इंजीनियर) के संस्करण के लिए एक गणितीय coprocessor के साथ मशीनों के साथ वितरित किया गया था। QuickBasic, के लिए MS-DOS संस्करण 4.0 और बाद में IEEE का उपयोग केवल। Microsoft IEEE मानक तीन प्राथमिक कारणों के लिए मूल के वर्तमान संस्करण में फ़्लोटिंग पॉइंट मान का प्रतिनिधित्व करने के लिए चुना है:

  1. Basic IEEE स्वरूप का उपयोग करें जिसमें Intel गणित coprocessors, का उपयोग करने के लिए अनुमति देने के लिए। Intel 80 x 87 श्रृंखला coprocessors Microsoft बायनेरी स्वरूप संख्याओं के साथ कार्य नहीं कर सकता।
  2. Interlanguage Basic, C, पास्कल, FORTRAN और MASM के बीच बहुत आसान कॉल करने के लिए। अन्यथा, कनवर्ज़न रूटिन संख्यात्मक मान एक भाषा से दूसरी करने के लिए भेजने के लिए उपयोग किया जा करने के लिए है चाहेंगे।
  3. स्थिरता प्राप्त करने के लिए। IEEE मानक C और FORTRAN compilers के लिए स्वीकृत उद्योग है।
निम्न IEEE और MBF प्रतिनिधित्व के लिए एक डबल-शुद्धता संख्या का एक त्वरित तुलना है:

               Sign Bits   Exponent Bits   Mantissa Bits
--------- ------------- -------------
IEEE 1 11 52 + 1 (Implied)
MBF 1 8 56


IEEE और MBF फ़्लोटिंग पॉइंट प्रतिनिधित्व, को Microsoft ज्ञानकोश में निम्न शब्द पर क्वेरी के बीच अंतर पर अधिक जानकारी के लिए:

   IEEE and floating and point and appnote


IEEE घातांक के लिए जो यह मान की एक व्यापक श्रृंखला का प्रतिनिधित्व करने के लिए अनुमति देता है, समर्पित और बिट्स है कि ध्यान दें। MBF और mantissa बिट्स, जो उसे और उसकी narrower श्रेणी में सटीक होना करने के लिए अनुमति देता है है।

फ़्लोटिंग पॉइंट सामान्य अवधारणाओं

यह केवल एक सीमित संख्या सटीक रूप में फ़्लोटिंग पॉइंट मानों की किसी भी बाइनरी फ़्लोटिंग पॉइंट सिस्टम का प्रतिनिधित्व कर सकते हैं महसूस करने के लिए बहुत महत्वपूर्ण है। अन्य सभी मान द्वारा representable निकटतम मान नहीं बदला जा करना होगा। IEEE मानक विधि "निकटतम" representable मान के लिए मान घुमाव के लिए निर्दिष्ट करता है। QuickBasic MS-DOS के लिए मानक का समर्थन करता है, और IEEE नियमों के अनुसार बनाता है।


साथ ही, संख्याएँ IEEE में प्रस्तुत किया जा सकता जो पर बहुत विस्तृत श्रेणी कर फैल जाते हैं मन में रखें। आप उन्हें एक नंबर लाइन पर कल्पना कर सकते हैं। एक उच्च घनत्व 1.0 और-1.0 के निकट representable संख्याओं का है, लेकिन के रूप में आप जाएँ 0 या अनंतता की ओर कम और कम है।


शुद्धता बढ़ाने के लिए IEEE मानक अभियांत्रिकी परिकलन के लिए डिज़ाइन किया गया है, जो, का लक्ष्य है (प्राप्त करने के लिए संख्या के रूप में बंद करने के लिए वास्तविक संभव के रूप में)। शुद्धता का प्रतिनिधित्व कर सकते हैं जो अंकों की संख्या को संदर्भित करता है। मानक IEEE सटीकता और शुद्धता स्वीकार्य सीमा के भीतर रखने के लिए, संख्या के भिन्नात्मक भाग के लिए उपयोग बिट्स की संख्या के साथ समर्पित करने के लिए घातांक बिट्स की संख्या संतुलित करने का प्रयास करता है।

IEEE विवरण

फ़्लोटिंग पॉइंट संख्या [घातांक] बाइनरी घातांक है जहाँ निम्न रूप में, प्रस्तुत हैं:

   X =  Fraction * 2^(exponent - bias)


[अंश] सामान्यीकृत घातांक समयोजित किया जाता है ताकि आगे बिट हमेशा किसी 1 है क्योंकि संख्या के साधारण भिन्नात्मक भाग है। इस तरह, इसे संग्रहीत करने के लिए नहीं है, और एक अधिक बिट की शुद्धता प्राप्त। यह है कि क्यों एक अव्यक्त बिट है। आप का जैसा वैज्ञानिक नोटेशन, जहाँ आप दशमलव बिंदु के बाईं ओर करने के लिए एक अंक को छोड़ कर जब में बायनरी, करने के लिए घातांक का परिचालन नहीं हैं, क्योंकि केवल 1s और 0s 1, पहली बिट है ताकि आप हमेशा घातांक परिचालन कर सकते हैं समझ सकते हैं।


[बायस] अभिनत मान नकारात्मक exponents संग्रहीत करने के लिए होने से बचने के लिए उपयोग किया जाता है।


एकल-शुद्धता संख्या के लिए बायस 127 और डबल-शुद्धता संख्या के लिए 1023 (दशमलव) है।


सभी 0 का मान बराबर और सभी 1 के (बाइनरी) विशेष मामलों का प्रतिनिधित्व करने के लिए आरक्षित हैं। विभिन्न त्रुटि स्थिति इंगित करती हैं कि अन्य विशेष मामलों में भी हैं।

एकल-शुद्धता उदाहरण

2 = 1 * 2 ^ 1 0100 0000 0000 0000 =... 0000 0000 0000 = 4000 हेक्स
नोट चिह्न बिट शून्य है, और संग्रहीत घातांक है 128 या 100 0000 में बायनरी, जो 127 और 1 0। संग्रहीत mantissa है (1.) 000 0000... जिससे वास्तविक mantissa है 1 0000 0000, जो एक अव्यक्त आगे 1 और बायनेरी बिंदु है।

-1 * -2 = 2 ^ 1 1100 0000 0000 0000 =... 0000 0000 = C000 0000 हेक्स
समान +2 सिवाय इसके कि चिह्न बिट सेट किया गया है। यह सभी IEEE स्वरूप फ़्लोटिंग पॉइंट संख्या के लिए सही है।

1 * 4 = 2 ^ 2 = 0100 0000 1000 0000... 0000 0000 0000 = 4080 हेक्स
एक ही mantissa घातांक द्वारा एक (biased मान 129, या 100 0000 में बायनरी 1 है. बढ़ाता है

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 1111 1000 0011 0000 =... 0000 0000 0000 = 3F80 हेक्स
2 की अन्य powers के रूप में एक ही घातांक mantissa है एक समय 127 या 011 1111 1 बायनरी में 2 से कम है।

1.5 *.75 = 2 ^ -1 = 0011 1111 0100 0000... 0000 0000 0000 = 3F40 हेक्स
Biased घातांक है 126, 011 1111 0 में बायनरी, और mantissa है (1.) 100 0000... 0000 0000, जो 1-1/2 है।

1.25 * 2.5 = 2 ^ 1 0100 0010 0000 0000 =... 0000 0000 0000 = 4020 हेक्स
निश्चित रूप से समान के रूप में जो तब को छोड़ कर 2 mantissa में जो 1/4 का प्रतिनिधित्व करने वाली बिट सेट किया गया है।

0.1 = 1.6 * 2 ^-4 = 0011 1101 1100 1100... 1100 1101 = 3DCC CCCD हेक्स
1/10 में बायनरी भिन्न दोहराए जाने वाले है। Biased घातांक कहता कि 1.6 16 से विभाजित नहीं किया जा करने के लिए है, और mantissa 1.6 का केवल shy है (इसे 011 1101 में बायनरी, दशमलव में 123 है जो 1 है)। सत्य घातांक है 123-127 = - 4, जिसका अर्थ है कि जो गुणा द्वारा फ़ैक्टर 2 * *-4 = 1/16 है। नोट संग्रहीत mantissa में अंतिम बिट पूर्णांक बनाया गया है। यह unrepresentable संख्या के रूप में सटीक रूप में संभव का प्रतिनिधित्व करने का एक प्रयास है। (कारण उस 1/10 और 1/100 में बायनरी representable बिल्कुल नहीं हैं 1/3 दशमलव में representable बिल्कुल नहीं है कि करने के तरीके के समान है.)

1.0 * 0 = 2 ^ -128 = सभी शून्य--एक विशेष मामला है।

अन्य सामान्य फ़्लोटिंग पॉइंट त्रुटि

फ़्लोटिंग पॉइंट सामान्य त्रुटियाँ निम्न हैं:

  1. राउंड-बंद त्रुटि


    जब सभी बिट्स को बाइनरी संख्या में किसी परिकलन में उपयोग किया जा सकता, तो यह त्रुटि परिणाम।


    उदाहरण: जोड़कर 0.9900 के लिए 0.0001 (एकल शुद्धता)


    0.0001 दशमलव के रूप में प्रस्तुत किया जा करेगा:
    (1.) 10100011011011100010111 * 2^(-14+Bias) (0s बाइनरी में अग्रणी 13!)
    0.9900 के रूप में प्रस्तुत किया जाएगा:
    (1.)11111010111000010100011 * 2^(-1+Bias)
    अब वास्तव में इन संख्याओं को जोड़ने के लिए, (बाइनरी) दशमलव बिंदु संरेखित होनी चाहिए। इसके लिए उन्हें होना चाहिए Unnormalized. परिणामस्वरूप प्राप्त होने वाली अतिरिक्त यहाँ है:
           .000000000000011010001101 * 2^0  <- Only 11 of 23 Bits retained
    +.111111010111000010100011 * 2^0
    ________________________________
    .111111010111011100110000 * 2^0


    कुछ कंप्यूटर्स पर shifting के अतिरिक्त राउंड, क्योंकि यह एक राउंड-बंद त्रुटि कहा जाता है। बस दूसरों के काटें। त्रुटियाँ राउंड-बंद करने पर विचार करने के लिए महत्वपूर्ण हैं जब भी आप जोड़ने या दो बहुत अलग मान multiplying है।
  2. मान घटाकर दो लगभग बराबर
           .1235
    -.1234
    _____
    .0001


    यह सामान्यीकृत किया जाएगा। नोट यद्यपि मूल संख्या प्रत्येक चार महत्वपूर्ण अंक थे, लेकिन परिणाम एक ही महत्वपूर्ण अंक है।
  3. ओवरफ़्लो और अंडरफ़्लो


    परिणाम डेटा प्रकार द्वारा प्रस्तुत किया जा करने के लिए बहुत छोटा या बहुत बड़ा है, जब ऐसा होता है।
  4. त्रुटि quantizing


    फ़्लोटिंग पॉइंट द्वारा मानक सटीक रूप में प्रस्तुत किया जा सकता उन संख्याओं के साथ ऐसा होता है।
  5. एक बहुत छोटी संख्या से भाग


    यह एक "शून्य से विभाजन" त्रुटि को ट्रिगर कर सकते हैं या गलत परिणाम, जैसा कि निम्न उदाहरण दे सकते हैं:
          A = 112000000
    B = 100000
    C = 0.0009
    X = A - B / C


    में 888887, मान के बजाय सही उत्तर, 900000 QuickBasic अभी X, MS-DOS के लिए है।
  6. आउटपुट त्रुटि


    इस प्रकार की त्रुटि तब होती है जब आउटपुट फ़ंक्शन परिवर्तित मानों के साथ वे काम कर रहे हैं।
गुण

आलेख ID: 42980 - पिछली समीक्षा: 18/01/2017 - संशोधन: 1

प्रतिक्रिया