2010-11-25 5 views
5

इस प्रश्न के प्रयोजनों के लिए, मैं में printf सुविधाओं का उपयोग करने की क्षमता रखने की क्षमता है (मैं आपको बता नहीं सकता कि दुर्भाग्यवश क्यों है, लेकिन आइए अब यह मान लें कि मैं जानता हूं कि मैं क्या कर रहा हूं)।आप आईईईई 754 नंबर (printf के बिना) कैसे प्रिंट करते हैं?

एक IEEE754 एकल परिशुद्धता संख्या के लिए, आप निम्नलिखित बिट्स है:

SEEE EEEE EFFF FFFF FFFF FFFF FFFF FFFF 

जहां S संकेत है, E प्रतिपादक और F अंश है।

संकेत मुद्रण, के रूप में, NaN (E == 0xff, F != 0), Inf (E == 0xff, F == 0) और 0 (E == 0, F == 0 की तरह सभी विशेष मामलों बढ़ रहा है विशेष माना जाता है सिर्फ इसलिए प्रतिपादक पूर्वाग्रह उस मामले में नहीं किया जाता है सभी मामलों के लिए अपेक्षाकृत आसान है)।

मेरे दो प्रश्न हैं।

पहला यह है कि सामान्यीकृत संख्याओं (जहां 1 <= E <= 0xfe) में denormalised संख्या (जहां E == 0, F != 0) को चालू करना सबसे अच्छा है? मुझे संदेह है कि अगले प्रश्न के उत्तर को सरल बनाना आवश्यक होगा (लेकिन मैं गलत हो सकता हूं इसलिए मुझे शिक्षित करने के लिए स्वतंत्र महसूस करें)।

दूसरा प्रश्न सामान्यीकृत संख्याओं को मुद्रित करना है। मैं उन्हें दो तरीकों से प्रिंट करने में सक्षम होना चाहता हूं, -3.74195E3 जैसे घातीय और 3741.95 जैसे गैर-घातीय। हालांकि, बस उन दोनों तरफ से देखकर, यह दशमलव को चारों ओर दशमलव बिंदु को स्थानांतरित करके पूर्व में बदलना काफी आसान होना चाहिए। तो चलिए घातीय रूप पर ध्यान केंद्रित करते हैं।

मैं जब दोनों सीमा सहमति एक एल्गोरिथ्म मैं बहुत पहले पीआई जहां आप कभी भी कम करने सूत्रों में से एक का इस्तेमाल किया और संभावनाओं पर एक ऊपरी और निचली सीमा रखा प्रिंट, एक अंकों outputting के लिए प्रयोग किया जाता है के एक अस्पष्ट याद है , और 10 के कारक द्वारा गणना को स्थानांतरित करना (इसलिए जब ऊपरी और निचली सीमा 3.2364 और 3.1234 थी, तो आप 3 आउटपुट कर सकते हैं और गणना के लिए समायोजित कर सकते हैं)।

लेकिन यह लंबा समय रहा है क्योंकि मैंने ऐसा किया है, इसलिए मुझे यह भी पता नहीं है कि यह यहां लेने के लिए उपयुक्त दृष्टिकोण है या नहीं। ऐसा लगता है क्योंकि प्रत्येक बिट का मान आंशिक भाग (1/2, 1/4, 1/8 और इसी तरह से आगे बढ़ते समय पिछली बिट का आधा है)।

मैं वास्तव में नहीं पसंद करते हैं printf स्रोत कोड के माध्यम से trudging जाना है जब तक बिल्कुल जरूरी तो है, अगर किसी को भी इस के साथ मदद कर सकते हैं, मैं सदा आभारी हो जाएगा होगा।

+0

क्या आपको तेज़ या किसी की इच्छा है? – ruslik

+1

यह एक अंधेरा कोने है, जिसमें subtleties हर मोड़ पर काटने का इंतजार कर रहे हैं। आपको सी रनटाइम लाइब्रेरी से कोड उठाने के लिए बेहतर तरीके से सेवा दी जा सकती है जो आपके इच्छित उपयोग की अनुमति देता है। बेशक, दूसरी दिशा को सही करने के लिए सही नहीं है ... – RBerteig

+0

यहां [eglibc कार्यान्वयन] है (http://www.eglibc.org/cgi-bin/viewcvs.cgi/branches/eglibc-2_12 /libc/stdio-common/printf_fp.c?rev=10495&view=markup)। ऐसा लगता है कि अच्छी तरह से टिप्पणी की गई है, लेकिन फिर भी पढ़ने के लिए कोई मजेदार नहीं है। –

उत्तर

3

यदि आप प्रत्येक रूपांतरण के लिए सटीक परिणाम प्राप्त करना चाहते हैं, तो आपको printf() कार्यान्वयन में किए गए मनमानी-सटीक अंकगणित का उपयोग करना होगा। यदि आप परिणाम प्राप्त करना चाहते हैं जो "करीबी" हैं, तो शायद उनके कम से कम महत्वपूर्ण अंकों में भिन्न हो सकते हैं, तो एक बहुत ही सरल डबल-परिशुद्धता आधारित एल्गोरिदम पर्याप्त होगा: पूर्णांक भाग के लिए, बार-बार दस से विभाजित करें और रहने वाले को जोड़ दें दशमलव स्ट्रिंग (रिवर्स में) बनाएं; आंशिक भाग के लिए, बार-बार दस गुना गुणा करें और दशमलव स्ट्रिंग बनाने के लिए पूर्णांक भागों को घटाएं।

मैंने हाल ही में इस विधि के बारे में एक लेख लिखा: http://www.exploringbinary.com/quick-and-dirty-floating-point-to-decimal-conversion/। यह वैज्ञानिक नोटेशन मुद्रित नहीं करता है, लेकिन यह जोड़ने के लिए तुच्छ होना चाहिए। एल्गोरिदम असामान्य संख्या प्रिंट करता है (जिन्हें मैंने मुद्रित किया है, सटीक रूप से बाहर आया है, लेकिन आपको अधिक गहन परीक्षण करना होगा)।

+0

+1 –

1

denormalized संख्याओं को उसी फ़्लोटिंग बिंदु प्रकार की सामान्यीकृत संख्या में परिवर्तित नहीं किया जा सकता है। समकक्ष सामान्यीकृत संख्या का एक्सपोनेंट एक्सपोनेंट द्वारा प्रतिनिधित्व करने के लिए बहुत छोटा होगा।

सामान्यीकृत संख्याओं को मुद्रित करने के लिए, एक मूर्ख तरीके से मैं सोच सकता हूं कि बार-बार 10 (अच्छी तरह से, आंशिक भाग के लिए) गुणा करना है।

+2

दिनचर्या फ्लोट के लिए किसी आंतरिक प्रतिनिधित्व का उपयोग कर सकती है, इसलिए यह कोई समस्या नहीं होगी। लिंक के लिए – ruslik

0

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

0

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

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