2010-11-10 12 views
8

मान लीजिए कि मेरे पास एक एपीआई है जो मुझे केवल फ्लोट्स या फ्लोट्स के सरणी स्टोर करने की अनुमति देती है। हालांकि, मैं यहां पूर्णांक मान संग्रहीत करना चाहता हूं।फ्लोट्स

मैं (लगभग) समझता हूं कि मैं सीधे 2^23 तक सीधे कलाकार के साथ ठीक हूं, लेकिन अगर मैं उच्च जाना चाहता हूं तो क्या होगा? क्या कोई तरीका है कि मैं एक फ्लोट के 32 बिट्स का अधिक लाभ उठा सकता हूं और सुनिश्चित कर सकता हूं कि मुझे वही नंबर वापस मिलेगा?


स्पष्टीकरण के लिए:

मैं पिक्सर के PRMan (। यानी RenderMan) के साथ बिंदु बादलों पर कुछ कार्यों कर रहा हूँ। मैं प्रीकंपिल्ड पॉइंट क्लाउड एपीआई के खिलाफ सी या सी ++ लिंकिंग में लिख सकता हूं। पीआरएमन को इन बिंदुओं का उपयोग करना है जो मैं भंडारित कर रहा हूं; मुझे केवल उन बिंदुओं से जुड़े अन्य डेटा पर काम करने के बाद मुझे वापस रखने के लिए इसे जरूरी है।

+2

हम किस भाषा के बारे में बात कर रहे हैं? –

+0

मैंने थोड़ा सा स्पष्ट किया। =] –

+0

यह भी ध्यान रखना महत्वपूर्ण है कि आप किस प्लेटफ़ॉर्म को जानते हैं कि फ्लोट कैसे कार्यान्वित किए जाते हैं। लेकिन यह शायद एक * वास्तव में * सुरक्षित शर्त है कि आप आईईईई फ्लोट का उपयोग कर रहे हैं। –

उत्तर

8

संदिग्ध:

सी में, आप निम्नलिखित है, जो संभावित रूप से असुरक्षित (सख्त अलियासिंग नियमों के कारण) है कर सकते हैं:

int i = XXX; 
float f; 
*(int *)&f = i; 

और जो धारणा है कि sizeof(int) == sizeof(float) पर निर्भर करता है।

कम संदिग्ध:

int i = XXX; 
float f; 
memcpy(&f, &i, sizeof(int)); 

यह अभी भी डेटा प्रकार आकार मिलान पर निर्भर करता है:

सुरक्षित है, लेकिन अधिक longwinded, निम्नलिखित है। हालांकि, उपर्युक्त दोनों इस धारणा को मानते हैं कि आप जिस लाइब्रेरी का उपयोग कर रहे हैं उसके आंतरिक डेटा डेटा पर सभी नहीं करेंगे। उदाहरण के लिए, यह आदि NaN के लिए कोई विशेष हैंडलिंग, या +/- अनंत,

सुरक्षित नहीं होगा:

सोचा था की एक बिल्कुल अलग ट्रेन के साथ, अगर आप दो बर्बाद करने के लिए खुश हैं

int i = XXX; 
float f[2] = { (i & 0xFFFF), ((unsigned)i >> 16 }; 

यह पिछले एक सुरक्षित है (तैरता और ints के आकार पर कुछ बहुत उचित मान्यताओं के अलावा अन्य): पूर्णांक प्रति तैरता है, आप की तरह कुछ कर सकता है।

+1

क्या आप सिर्फ f [1] के लिए i >> 16 का उपयोग नहीं करेंगे? – MSN

+0

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

+0

@ मार्टिन: हाँ, मैंने इसके जवाब में इसका संकेत दिया है। –

3

मंटिसा फ़ील्ड आपको 23 बिट्स स्टोर करने देता है। एक्सपोनेंट फ़ील्ड आपको लगभग 8 बिट स्टोर करने देता है, यह कुछ मान आरक्षित के साथ 8 बिट चौड़ा है। और एक संकेत बिट है।

एक्सपोनेंट में आरक्षित मूल्यों से बचना, आप अभी भी अपनी पसंद के 31 बिट स्टोर कर सकते हैं।

आपको frexp और ldexp उपयोगी मिल सकता है।

0

यहां दिए गए सभी उत्तरों का मानना ​​है कि आप केवल एक इंट स्टोर करने के लिए फ्लोट स्टोरेज के लिए आरक्षित बाइट्स का उपयोग करना चाहते हैं। वे आपको int-encoded-in-float मानों पर अंकगणित करने की अनुमति नहीं देंगे। यदि आप अंकगणित काम करना चाहते हैं, तो आप 24.9 9 बिट्स (यानी एक श्रेणी (2^24-1) से (2^24-1) के साथ अटक गए हैं; मैं साइन बिट को 1 बिट के बजाय 0.9 9 बिट्स के रूप में मानता हूं क्योंकि आप फ्लोट के संकेत/परिमाण प्रतिनिधित्व के साथ सबसे कम संभव मूल्य को स्टोर नहीं कर सकता) और बड़े मूल्यों का एक अलग सेट (उदा।256 के किसी भी 32-बिट पूर्णांक एकाधिक फ्लोट में प्रतिनिधित्व योग्य है)।

+0

यह 24 बिट्स होना चाहिए, नहीं? सिंगल-प्रेसिजन में 1 साइन बिट और 23 मंटिसा बिट्स हैं। –

संबंधित मुद्दे