फ्लोटिंग पॉइंट नंबरों का रिज़ॉल्यूशन एक मूल से आगे क्यों घटता है?


19

मेरे ओपनजीएल दृश्य में ऐसी वस्तुएं हैं जो मूल से दूर दूर तक हास्यास्पद रूप से तैनात हैं। जब मैं इन वस्तुओं को देखता हूं, और अपने चारों ओर एक कैमरा पैन / रोटेट / ज़ूम करता हूं, तो वे 'घबराना' करते हैं। यही है, वस्तुओं को शामिल करने वाले कोने बिंदुओं के काल्पनिक 3 डी ग्रिड के आसपास स्नैप करने लगते हैं। मैंने पढ़ा है कि यह एक सामान्य समस्या है क्योंकि जानकारी की मात्रा जो फ़्लोटिंग पॉइंट प्रिसिजन का उपयोग करके संग्रहित की जा सकती है (जो कि ओपनजीएल, और बहुत अधिक हर चीज का उपयोग करती है)। मुझे नहीं लगता कि ऐसा क्यों होता है।

एक समाधान की खोज करते समय, मैं बहुत ही सरल 'फ्लोटिंग ओरिजिनल' फिक्स के साथ आया, और यह काम करने लगता है। मैं बस सब कुछ बदल देता हूं, इसलिए मेरी वस्तुएं समान सापेक्ष स्थिति में हैं लेकिन मेरे कैमरे की जो भी उत्पत्ति है वह करीब है। मुझे यहाँ एक स्पष्टीकरण मिला: http://floatingorigin.com/ , लेकिन मैं इसका पालन नहीं कर सका।

इसलिए ... क्या कोई समझा सकता है कि मूल दृश्य से मेरे दृश्य को बहुत दूर रखने (10 मिलियन यूनिट कहने) के कारण मेरे द्वारा किए गए अनियमित व्यवहार का परिणाम है? और यह भी क्यों इसे मूल के करीब ले जाने से समस्या ठीक हो जाती है?


4
क्योंकि अगर वे नहीं करते हैं, तो वे निश्चित- अंक संख्या होंगे। तात्त्विक प्रश्न, यह।
MSalters

1
सच है, लेकिन केवल जब आप समझते हैं कि 'फ्लोटिंग पॉइंट' का सही मतलब क्या है।
काइलोटन

जवाबों:


26

यह सब कंप्यूटर में फ्लोटिंग पॉइंट्स को दर्शाने के तरीके के कारण होता है।

पूर्णांक बहुत सीधे संग्रहीत हैं; प्रत्येक इकाई बिल्कुल "एक" है, "पिछले" के अलावा, जैसा कि आप गणना करने योग्य संख्याओं के साथ उम्मीद करेंगे।

फ्लोटिंग पॉइंट नंबरों के साथ ऐसा बिल्कुल नहीं है। इसके बजाय, कई बिट्स प्रतिपादक से संकेत मिलता है, और बाकी का संकेत मिलता है क्या के रूप में जाना जाता है अपूर्णांश , या आंशिक भाग जाता है कि तो प्रतिपादक हिस्सा (परोक्ष 2 ^ exp) से गुणा अंतिम परिणाम देने के लिए।

बिट्स की एक दृश्य व्याख्या के लिए यहां देखें ।

यह ठीक है कि इस घातांक के बिट्स का एक वास्तविक हिस्सा होने के कारण सटीकता बड़ी संख्या में बढ़ने के बाद WANE से शुरू होती है।

इस क्रिया को देखने के लिए, चलिए एक फ्लोटिंग-फ्लोटिंग पॉइंट निरूपण को बिना किसी किरकिरी के करें: 2 जैसा एक छोटा सा घातांक लें और परीक्षण करने के लिए कुछ भिन्नात्मक भाग करें:

2 * 2 ^ 2 = 8

3 * 2 ^ 2 = 12

4 * 2 ^ 2 = 16

...आदि।

ये संख्याएँ केवल घातांक 2 से बहुत दूर नहीं बढ़ती हैं। लेकिन अब हम घातांक 38 की कोशिश करते हैं:

2 * 2 ^ 38 = 549755813888

3 * 2 ^ 38 = 824633720832

4 * 2 ^ 38 = 1099511627776

वाह, अब भारी अंतर!

उदाहरण, जबकि विशेष रूप से VERY NEXT COUNTABLE पर नहीं जा रहा है (कि कितने बिट्स के आधार पर यह अगला अगला आंशिक भाग होगा), संख्या बड़ी होने के बाद सटीक हानि प्रदर्शित करने के लिए है। फ्लोट्स में "अगला काउंटेबल" यूनिट छोटे एक्सप्लोसर्स के साथ बहुत छोटा है और बड़े एक्सप्लर्स के साथ बहुत बड़ा है, जबकि पूर्णांकों में यह हमेशा 1 है।

फ्लोट उत्पत्ति विधि काम करने का कारण यह है क्योंकि यह इन सभी संभावित बड़े-एक्सपोनेंट फ़्लोटिंग पॉइंट नंबर DOWN TO small-exponent को स्केल कर रहा है ताकि "अगला काउंटेबल्स" (परिशुद्धता) बहुत छोटा और खुश हो सके।


आपके द्वारा दिए गए उदाहरण वास्तव में सचित्र थे, धन्यवाद :)
Pris

3
सही रास्ते पर, लेकिन मेरी इच्छा है कि आपने ऐसे उदाहरणों का उपयोग किया हो जो वास्तव में काम करने के तरीके के करीब हों। यह घातांक को mantissa नहीं बढ़ाता है; यह मंटिसा * 2 ^ प्रतिपादक है।
नाथन रीड

3
तुम सही हो, मुझे पता था कि; मुझे नहीं पता कि मैं क्या सोच रहा था। मेरे उत्तर का संपादन किया।

1
@ScottW अच्छा संपादन! +1
नाथन रीड

17

क्योंकि फ़्लोटिंग पॉइंट संख्याओं को अंश + प्रतिपादक + संकेत के रूप में दर्शाया जाता है, और आपके पास अंश भाग के लिए केवल बिट्स की एक निश्चित राशि होती है।

http://en.wikipedia.org/wiki/Single_precision

जैसा कि आप बड़े और बड़े नंबर प्राप्त करते हैं, आपके पास छोटे भागों का प्रतिनिधित्व करने के लिए बस बिट्स नहीं होते हैं।


8

क्षेत्र में क्लासिक को लाया जाना चाहिए: फ्लोटिंग पॉइंट नंबरों के बारे में हर कंप्यूटर वैज्ञानिक को पता होना चाहिए

लेकिन इसका सार यह है कि सिंगल (डबल) सटीक फ्लोटिंग पॉइंट नंबरों के साथ क्या करना है, बस एक 32 बिट (64-बिट) बाइनरी नंबर है जो कि 1 बिट का प्रतिनिधित्व करता है, बेस 2 का 8-बिट (11-बिट) एक्सपोनेंट , और 23 बिट (52-बिट) महत्व (कोष्ठक युगल के लिए मान हैं)।

इसका मतलब है कि सबसे छोटी धनात्मक संख्या जिसे आप एकल सटीकता में दर्शा सकते हैं, 0.0000000000000000000001 x 2 -127 = 2 -22 x 2 -127 = 2 -149 ~ 1.40 x 10 -45 है

अगले धनात्मक संख्या डबल है कि: 0.0000000000000000000010 एक्स 2 -127 = 2 -148 ~ 2.80 x 10 -45 , और फिर अगले संख्या पिछले दो 0.0000000000000000000011 एक्स 2 का योग है -127 = 3 एक्स 2 -149 ~ 4.2 - ४५

यह उसी निरंतर अंतर से बढ़ रहा है जब तक: 0.111111111111111111111111 x 2 -127 = 2 -126 - 2 149 ~ 1.17549435 x 10 -38 - 0.00000014 x 10 -38 = 1.17549421 x 10 -38

अब आप सामान्य संख्या तक पहुँच गए हैं (जहाँ महत्व में पहला अंक 1 है) विशेष रूप से: 1.0000000000000000000000 x 2 -126 = 2 -126 = 1.17549435 x 10 -38 और फिर अगला नंबर है 1.0000000000000000000000 x 2 -126 = 2 -126 (1 + 2 -22 ) = 1.17549435 x 1.00000023।


2

मूल से आगे फ़्लोटिंग-पॉइंट संख्या कम सटीक होने का कारण यह है कि फ़्लोटिंग-पॉइंट नंबर बड़ी संख्याओं का प्रतिनिधित्व करने में सक्षम माना जाता है। जिस तरह से यह किया जाता है वह इसे "फ्लोटिंग पॉइंट" शब्द देता है। यह उन संभावित मूल्यों को विभाजित करता है जो इसे ले सकते हैं (जो इसकी बिट-लंबाई द्वारा निर्धारित किया जाता है) ताकि प्रत्येक प्रतिपादक के लिए एक ही संख्या हो: 32-बिट फ्लोट के लिए, 23 बिट्स मेंटिस या महत्व को परिभाषित करते हैं। तो यह प्रत्येक घातांक सीमा में 2 ^ 23 विभिन्न मानों का मान ले सकेगा। इन घातांक श्रेणियों में से एक 1-2 [2 ^ 0 से 2 ^ 1] है, इसलिए सीमा 1 से 2 को 2 ^ 23 विभिन्न मूल्यों में विभाजित करने से बहुत अधिक सटीकता की अनुमति मिलती है।

लेकिन सीमा [2 ^ 10 से 2 ^ 11] को 2 ^ 23 भिन्न मानों में विभाजित करने का अर्थ है कि प्रत्येक मान के बीच का स्थान बहुत बड़ा है। यदि ऐसा नहीं होता, तो 23 बिट्स पर्याप्त नहीं होंगे। पूरी बात एक समझौता है: किसी भी वास्तविक संख्या का प्रतिनिधित्व करने के लिए आपको अनंत संख्या में बिट्स की आवश्यकता होती है। यदि आपका एप्लिकेशन इस तरह से काम करता है जो आपको बड़े मूल्यों के लिए कम सटीकता के साथ दूर जाने देता है, और आप वास्तव में बड़े मूल्यों का प्रतिनिधित्व करने में सक्षम होने से लाभ उठाते हैं , तो आप एक फ्लोटिंग पॉइंट प्रतिनिधित्व का उपयोग करते हैं।


बस 7 साल बाद आगे की समीक्षा पर यहाँ एक नोट बना रहा हूँ ... मेरे उदाहरणों में मेरे नंबर विशेष रूप से अच्छी तरह से चुने नहीं गए हैं। लेकिन समग्र अंक मान्य हैं।
स्टीवन लू

1

फ्लोटिंग-पॉइंट सटीक कैसे काम करता है, इसके विशिष्ट उदाहरण पेश करना थोड़ा मुश्किल हो सकता है। अन्य उत्तरों के पूरक के लिए, यहाँ एक है। मान लें कि हमारे पास एक दशमलव फ्लोटिंग-पॉइंट संख्या है, जिसमें तीन अंक मंटिसा और एक अंक घातांक है:

mantissa × 10 घातांक

जब प्रतिपादक 0 होता है, तो 0–999 की सीमा में प्रत्येक पूर्णांक को सटीक रूप से दर्शाया जा सकता है। जब यह 1 हो, तो आप अनिवार्य रूप से उस श्रेणी के प्रत्येक तत्व को 10 से गुणा कर रहे हैं, इसलिए आपको 09990 की सीमा मिलती है; लेकिन अब, केवल 10 के गुणकों को सही ढंग से दर्शाया जा सकता है, क्योंकि आपके पास अभी भी केवल तीन अंक हैं। जब घातांक अपने अधिकतम 9 पर होता है, तो प्रत्येक जोड़े के प्रतिनिधित्व योग्य पूर्णांकों के बीच का अंतर एक अरब होता है । आप वस्तुतः रेंज के लिए सटीक व्यापार कर रहे हैं।

यह बाइनरी फ़्लोटिंग-पॉइंट नंबरों के साथ उसी तरह से काम करता है: जब भी एक्सपोनेंट एक से बढ़ जाता है, तो सीमा दोगुनी हो जाती है , लेकिन उस सीमा के भीतर प्रतिनिधित्व करने योग्य मानों की संख्या आधी हो जाती है । यह भिन्नात्मक संख्याओं पर भी लागू होता है, जो निश्चित रूप से आपकी समस्या का स्रोत है।


0

सामान्य तौर पर, रिज़ॉल्यूशन खराब हो जाता है क्योंकि रिज़ॉल्यूशन एक्सपोनेंट वैल्यू (2 ** एक्सपोनेंट पार्ट) से गुणा होता है।

जोश की टिप्पणी को स्वीकार करने में: उपरोक्त केवल एक संक्षिप्त बयान में जवाब देने के लिए था। बेशक, जैसा कि मैंने http://floatingorigin.com/ पर इंगित करने की कोशिश की है , यह सिर्फ एक समग्र समाधान की ओर शुरू हो रहा है और आपके कार्यक्रम में कई स्थानों से घबराना हो सकता है: सटीक पाइपलाइन या कोड के अन्य भागों में। ।


यह कुछ भी नहीं जोड़ता है जो पहले से ही अन्य उत्तरों में मौजूद नहीं है।

सच: मुझे एहसास हुआ कि मैं एक ही पंक्ति में उत्तर का वर्णन कर सकता हूं और सोचा कि किसी को एक सफल उत्तर उपयोगी मिल सकता है।
क्रिस थॉर्न

-1

OpenGL गहराई बफर रैखिक नहीं है । आप जितना दूर जाते हैं, उतना ही बुरा संकल्प होता है। मैं पढ़ने के लिए सलाह देते हैं इस । वहां से लिया गया कुछ (12.070):

सारांश में, परिप्रेक्ष्य, इसकी प्रकृति से विभाजित होता है, पीठ के निकट की तुलना में दृश्य मात्रा के सामने अधिक Z परिशुद्धता का कारण बनता है।

और दूसरा एक (12.040):

आप अपने zNear और zFar कतरन विमानों को इस तरह से कॉन्फ़िगर कर सकते हैं जो आपकी गहराई बफर सटीकता को गंभीर रूप से सीमित करता है। आम तौर पर, यह एक zNear कतरन विमान मूल्य के कारण होता है जो 0.0 के करीब है। जैसा कि zNear कतरन विमान तेजी से 0.0 के करीब सेट है, गहराई बफर की प्रभावी परिशुद्धता नाटकीय रूप से घट जाती है। ZFar क्लिपिंग प्लेन को आँख से दूर ले जाने पर हमेशा गहराई बफर परिशुद्धता पर नकारात्मक प्रभाव पड़ता है, लेकिन यह zNear कतरन विमान को हिलाने के रूप में नाटकीय नहीं है।

तो आप अपने पास कतरन विमान के पास जाना चाहिए आप कर सकते हैं और अपने सबसे दूर विमान आप कर सकते हैं निकटतम।


-1: सवाल फ्लोटिंग-पॉइंट प्रिसिजन के बारे में है, न कि लीनियर डेप्थ बफर प्रतिनिधित्व के साथ सटीक मुद्दों पर।
नाथन रीड

यह संभव है कि मैं जो देख रहा हूं वह गहराई से बफरिंग मुद्दों के कारण है। मैं अपने दृश्य को देखने के लिए ओपनजीएल के शीर्ष पर एक परिवाद का उपयोग कर रहा हूं, और मैं ज्यामिति के आकार और स्थिति को देखने के लिए कैमरा, दृश्य, और निकट और दूर की कतरन वाले विमानों की स्थापना की धारणा बना रहा हूं (दर्शक के बाद से उपकरण स्वचालित रूप से दृश्य सामग्री के लिए एक इष्टतम दृश्य सेट करता है)। लेकिन मुझे लगता है कि यह मामला नहीं हो सकता है - मैं मूल स्थिति को छोड़ते हुए कतरन वाले विमानों के साथ खेलने की कोशिश करूंगा और देखूंगा कि क्या होता है।
प्रिस

2 नथन रीड: लेखक ने लिखा है, कि उसके पास ओपनगैल दृश्य है, इसलिए मैंने सोचा, यह इस मुद्दे पर भी हो सकता है।
zacharmarz

यह समस्या समान या संबंधित लग सकती है, लेकिन गहराई बफ़र मान निश्चित रूप से फ़्लोटिंग पॉइंट नंबरों के साथ संगत तरीके से संग्रहीत नहीं हैं। यह एक निश्चित बिंदु प्रारूप है। यह इस वजह से है कि उत्तर भ्रामक हो सकता है।
स्टीवन लू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.