2012-04-28 40 views
7

सबसे पहले, यह परिशुद्धता या उसके जैसा कुछ भी नहीं है।बाइनरी संख्या का प्रतिनिधित्व

मेरा सवाल यह है कि संकलक कैसे एक संख्या का प्रतिनिधित्व करने का निर्णय लेता है?

चलिए उदाहरण के लिए सी लेते हैं। मैं

double d = 4.5632; 

यह अपने बाइनरी प्रतिनिधित्व को कैसे चुनता है? मुझे पता है कि यह बिल्कुल प्रतिनिधित्व नहीं किया गया है, तो यह निकटतम प्रतिनिधित्व करने योग्य संख्या का चयन कैसे करता है? क्या यह संकलन समय पर किया जाता है? क्या यह सीपीयू या ओएस द्वारा किया जाता है?

कृपया केवल उत्तर दें यदि आप जानते हैं कि यह कैसे होता है, तो "इसके बारे में चिंता न करें" जैसे उत्तर उपयोगी नहीं हैं। साथ ही, "यह मंच पर निर्भर करता है" सहायक भी नहीं है, आप एक मंच चुन सकते हैं और इसके लिए समझा सकते हैं।

+3

कंप्यूटर "लेने" नहीं द्विआधारी प्रतिनिधित्व - हार्डवेयर डिजाइनरों और संकलक लेखकों से करते हैं। [इस मानक] पर एक नज़र डालें (http://en.wikipedia.org/wiki/IEEE_754-2008)। – dasblinkenlight

उत्तर

6

कंपाइलर (आमतौर पर) तय नहीं करता है। सीपीयू (आमतौर पर) में एक फ्लोटिंग-पॉइंट इकाई होती है, जिसके लिए फ्लोटिंग-पॉइंट मानों को किसी विशेष प्रारूप में प्रदर्शित करने की आवश्यकता होती है (यह आमतौर पर IEEE-754 है)। बेशक, एक पूरी तरह से अलग वास्तुकला का अनुकरण करना संभव है, इस मामले में संकलक/एमुलेटर लेखक पूरी तरह से अलग प्रतिनिधित्व लेने के लिए स्वतंत्र है। लेकिन यह सामान्य नहीं है।

विशिष्ट व्याख्यात्मक प्रतिनिधित्व 4.5632 को अंतर्निहित प्रतिनिधित्व में परिवर्तित किया गया है, जो सी मानक द्वारा निर्दिष्ट है। तो C99 मानक की धारा 6.4.4.2 से (मैं सबसे अधिक प्रासंगिक भाग पर प्रकाश डाला गया है):

significand भाग एक (दशमलव या हेक्साडेसिमल) तर्कसंगत संख्या के रूप में व्याख्या की है, एक्सपोनेंट भाग में अंक अनुक्रम दशमलव पूर्णांक के रूप में व्याख्या किया गया है। दशमलव फ़्लोटिंग स्थिरांक के लिए, एक्सपोनेंट 10 की शक्ति इंगित करता है जिसके द्वारा महत्वपूर्ण भाग को स्केल किया जा सकता है। हेक्साडेसिमल फ्लोटिंग स्थिरांक के लिए, एक्सपोनेंट इंगित करता है कि 2 की शक्ति जिसके द्वारा महत्वपूर्ण भाग को स्केल किया जाना है। दशमलव चल स्थिरांक के लिए, और यह भी हेक्साडेसिमल चल स्थिरांक जब FLT_RADIX, 2 की एक शक्ति नहीं है परिणाम या तो निकटतम प्रदर्शनीय मूल्य, या बड़ा या छोटा प्रदर्शनीय मूल्य तुरंत निकटतम प्रदर्शनीय मूल्य के निकट चुना है के लिए कार्यान्वयन-परिभाषित तरीके से। हेक्साडेसिमल फ्लोटिंग स्थिरांक के लिए जब FLT_RADIX 2 की शक्ति है, तो परिणाम सही ढंग से गोलाकार है।

यह संकलन समय पर किया जाएगा (हालांकि मानक इसे जरूरी नहीं है)।

+0

और यह मानक – nullpotent

+0

पर निर्भर करता है यह मेरे प्रश्न का उत्तर नहीं देता - कैसे? यह कैसे पता चलता है कि 3.14 का प्रतिनिधित्व 0100111010 द्वारा किया जाना चाहिए .... या जो भी हो? – AMCoder

+0

@AMCoder: मैंने आपके प्रश्न को गलत समझा। अद्यतन देखें। –

0

हां, यह विशेष रूपांतरण संकलन समय पर किया जाता है, क्योंकि double d = 4.5632; एक संकलन-समय स्थिर है। आपके कोड में संकलित किया गया है लक्ष्य आर्किटेक्चर द्वारा उपयोग किए जाने वाले फ़्लोटिंग-पॉइंट प्रारूप में इस मान का प्रतिनिधित्व है। 32-बिट आईईईई -754 प्रतिनिधित्व के मामले में, यह 0x409205BC है। सीपीयू कैसे जानता है कि यह 4.5632 के करीब कुछ मूल्य है, जो फ्लोटिंग-पॉइंट मानक पर निर्भर है। फिर, 32-बिट आईईईई -754 के मामले में, हमारे पास साइन के लिए एक बिट, एक्सपोनेंट के लिए आठ बिट्स और मंटिसा के लिए 23 बिट्स हैं।

जब गोल करने की बात आती है, तो कई विधियां लागू की जा सकती हैं। आईईईई -754 विनिर्देश चार तरीकों का उल्लेख करता है: निकटतम, गोल से शून्य, नकारात्मक अनंत तक गोल, सकारात्मक अनंतता के दौर के लिए।

0

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

प्रैक्टिस में, लगभग सभी प्लेटफार्म आईईईई 754, उर्फ ​​आईईसी 55 9 के अनुसार फ्लोटिंग-पॉइंट अंकगणितीय लागू करते हैं। यह काफी पुराना अंतरराष्ट्रीय मानक परिभाषित करता है कि फ़्लोटिंग-पॉइंट नंबर के बिट्स का क्या मतलब है, और प्रोग्राम दशमलव प्रतिनिधित्व को कैसे गोल किया जाना चाहिए एक फ्लोटिंग-पॉइंट मान पर।

कोई एफपीयू वाला प्लेटफार्म अभी भी सॉफ्टवेयर में आईईईई 754 नंबरों से बिटफिल्ड को पैक और अनपैक करेगा, क्योंकि वे फाइलों में बाइनरी फॉर्म में दिखाई देने की संभावना है।

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

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

0

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

double d; int a; 
a 45632; 
d = a; 
d/=10000; 

और यहां तक ​​कि यदि यह अनुकूलित करता है तो यह बेहतर, अधिक सटीक, उत्तर प्राप्त करता है।

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

यह सब कुछ दिखाता है क्योंकि मैंने यह सब दिखाया है, शायद कंपेलरों को बेहतर (संदिग्ध) मिल गया है। उम्मीद है कि हार्डवेयर बेहतर हो गया है (संभवतः, यह एक fpu खोजने के लिए बहुत दुर्लभ होता था बिना बग खोजने के लिए)।

+0

आईईईई 754 फ्लोटिंग पॉइंट प्रारूप आमतौर पर उपयोग किया जाता है। लेकिन यह आपके सिस्टम पर हार्डवेयर एफपीयू होने पर हार्डवेयर पर निर्भर करता है, तो हार्डवेयर का उपयोग करने वाले किसी भी प्रारूप की संभावना है कि संकलक किस प्रकार संकलित करता है। यदि यह एक नरम fpu है तो यह नरम fpu चाहता है जो भी प्रारूप है। आईईईई सुविधाओं के असंख्य के कारण कठिन/धीमी/कम विश्वसनीय प्रारूप है। उदाहरण के लिए टीआई डीएसपी प्रारूप काफी साफ, तेज, अधिक विश्वसनीय है, लेकिन इसमें कोई गोलाकार या अनंत या नन नहीं है। –

0

आपका विशेष उदाहरण संकलक द्वारा परिवर्तित किया गया है क्योंकि यह दशमलव अक्षर है। आप विनिर्देश चाहते हैं, तो चलिए जीसीसी चुनते हैं। यह real.c में रूपांतरण करता है (मुझे नहीं पता कि यह वर्तमान संस्करण है, लेकिन यह Google की पहली प्रतिलिपि थी जिसे मैंने real_from_string() नामक फ़ंक्शन में किया था। यह अनिवार्य रूप से एक लंबे विभाजन के साथ रूपांतरण करता है: आपके मामले में, 45632/10000।

(फ्लोटिंग प्वाइंट रूपांतरण के लिए दशमलव काफी शामिल है; my blog की जाँच करता है, तो आप और अधिक जानना चाहते हैं।)