2010-01-27 6 views
10

मुझे यह जानना है कि क्या मैं मान सकता हूं कि उसी 64-बिट फ्लोटिंग पॉइंट नंबरों पर वही ऑपरेशन किसी भी आधुनिक पीसी और सबसे आम प्रोग्रामिंग भाषाओं में बिल्कुल वही परिणाम देता है? (सी ++, जावा, सी #, आदि)। हम मान सकते हैं कि हम संख्याओं पर परिचालन कर रहे हैं और नतीजा भी एक संख्या है (कोई नाएन, आईएनएफ और इसी तरह)।क्या 64-बिट फ्लोटिंग पॉइंट नंबर सभी आधुनिक पीसी पर समान व्यवहार करते हैं?

मुझे पता है कि फ्लोटिंग पॉइंट नंबर (आईईईई 854-1987 और आईईईई 754-2008) का उपयोग करके गणना के दो बहुत ही समान मानक हैं। हालांकि मुझे नहीं पता कि यह अभ्यास में कैसा है।

उत्तर

8

आधुनिक प्रोसेसर है कि 64-बिट फ्लोटिंग प्वाइंट लागू आम तौर पर कुछ है कि आईईईई 754-1985 मानक, हाल ही में 754-2008 मानक द्वारा अधिक्रमण के करीब है को लागू।

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

इस वजह से, जिन परिचालनों में अतिप्रवाह जैसी अपवाद स्थितियां शामिल नहीं हैं, वे मानक के अनुरूप विभिन्न प्रोसेसर पर समान परिणाम प्राप्त करेंगे।

हालांकि, कई समस्याएं हैं जो विभिन्न प्रोसेसर पर समान परिणाम प्राप्त करने में हस्तक्षेप करती हैं। उनमें से एक यह है कि संकलक अक्सर विभिन्न तरीकों से फ़्लोटिंग-पॉइंट ऑपरेशंस के अनुक्रमों को लागू करने के लिए स्वतंत्र होता है। उदाहरण के लिए, यदि आप सी में "ए = बी सी + डी" लिखते हैं, जहां सभी चर को डबल घोषित किया जाता है, तो कंपाइलर डबल बी-परिशुद्धता अंकगणित या अधिक रेंज या परिशुद्धता वाले कुछ "बी सी" की गणना करने के लिए स्वतंत्र है। यदि, उदाहरण के लिए, प्रोसेसर में विस्तारित-परिशुद्धता फ्लोटिंग-पॉइंट संख्याओं को रखने में सक्षम रजिस्ट्रार होते हैं और विस्तारित-परिशुद्धता के साथ अंकगणित करते हैं, तो डबल-परिशुद्धता के साथ अंकगणित करने से अधिक CPU समय नहीं लेता है, एक कंपाइलर विस्तारित करके कोड उत्पन्न करने की संभावना है -precision। ऐसे प्रोसेसर पर, आपको एक ही प्रोसेसर के समान परिणाम नहीं मिलेंगे। यहां तक ​​कि यदि संकलक नियमित रूप से ऐसा करता है, तो हो सकता है कि यह कुछ परिस्थितियों में न हो क्योंकि रजिस्ट्रार जटिल अनुक्रम के दौरान पूर्ण होते हैं, इसलिए यह मध्यवर्ती परिणामों को अस्थायी रूप से स्मृति में संग्रहीत करता है। जब ऐसा होता है, तो यह विस्तारित-सटीक संख्या के बजाय केवल 64-बिट डबल लिख सकता है। इसलिए फ्लोटिंग-पॉइंट अंकगणित युक्त एक नियमित रूप से अलग-अलग परिणाम दे सकते हैं क्योंकि इसे अलग-अलग कोड के साथ संकलित किया गया था, शायद एक स्थान पर रेखांकित किया गया था, और संकलक को किसी अन्य चीज़ के लिए रजिस्ट्रार की आवश्यकता होती है।

कुछ प्रोसेसरों एक गुणा और एक अनुदेश में एक ऐड, तो "ख सी + डी" कोई मध्यवर्ती राउंडिंग के साथ गणना की जा सकती है की गणना और है कि पहले की गणना करता है ख ग एक प्रोसेसर की तुलना में एक अधिक सटीक परिणाम प्राप्त करने के निर्देश और फिर डी जोड़ता है।

आपके कंपाइलर इस तरह के व्यवहार को नियंत्रित करने के लिए स्विच कर सकते हैं।

कुछ ऐसे स्थान हैं जहां 754-19 85 मानक को अद्वितीय परिणाम की आवश्यकता नहीं होती है। उदाहरण के लिए, यह निर्धारित करते समय कि अंडरफ्लो हुआ है (परिणामस्वरूप सटीक रूप से प्रतिनिधित्व करने के लिए बहुत छोटा है), मानक लक्ष्यीकरण परिशुद्धता के लिए महत्व (अंश बिट्स) के चारों ओर या उसके बाद निर्धारण को कार्यान्वित करने की अनुमति देता है। तो कुछ कार्यान्वयन आपको बताएंगे कि अन्य कार्यान्वयन कब नहीं होंगे।

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

ध्यान दें कि एक आईईईई 754 कार्यान्वयन आमतौर पर हार्डवेयर द्वारा प्रदान नहीं किया जाता है बल्कि हार्डवेयर और सॉफ्टवेयर के संयोजन द्वारा प्रदान किया जाता है। प्रोसेसर काम का बड़ा हिस्सा कर सकता है लेकिन कुछ अपवादों को संभालने के लिए सॉफ़्टवेयर पर निर्भर करता है, कुछ मोड सेट करता है, और इसी तरह।

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

संक्षेप में, यदि आपके पास गणना का एक प्रबंधित सेट है, तो अपने कंपाइलर कार्यान्वयन को समझें, और बहुत सावधान हैं, आप विभिन्न प्रोसेसर पर समान परिणामों पर भरोसा कर सकते हैं। अन्यथा, पूरी तरह से समान परिणाम प्राप्त करना ऐसा कुछ नहीं है जिस पर आप भरोसा कर सकते हैं।

+0

सभी अच्छे अंक। हार्डवेयर के उदाहरण के लिए जो विभिन्न परिणाम देता है, x86_64 (यानी सभी इंटेल पेंटियम क्लास प्रोसेसर) k1om (यानी इंटेल फाई उर्फ ​​इंटेल एमआईसी) से अलग परिणाम देता है। आंतरिक रजिस्ट्रार अलग-अलग आकार होते हैं, भले ही बाहरी 64-बिट मेमोरी प्रस्तुति (आईईईई 754) समान है। –

2

आधुनिक एफपीयू सभी एकल और डबल प्रारूपों में आईईईई 754 फ्लोट को लागू करते हैं, और कुछ विस्तारित प्रारूप में। परिचालनों का एक निश्चित सेट समर्थित है (math.h में काफी कुछ भी), कुछ विशेष निर्देशों के साथ वहां तैरते हुए।

+0

सच है, लेकिन आईईईई आपको पुनरुत्पादन के लिए क्या गारंटी देता है? – ergosys

+0

कोई नहीं, क्योंकि इंटेल FDIV बग दिखाया गया है। –

1

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

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

0

64-बिट डेटा प्रकार के लिए, मुझे केवल आईईईई 754 (1 9 85 और 2008 के सामान्य मामलों के लिए बहुत अलग नहीं है) से "double precision"/"binary64" पता है।

नोट: आईईईई 854-1987 में परिभाषित रेडिक्स प्रकारों को आईईईई 754-2008 द्वारा किसी भी तरह से हटा दिया गया है।

1

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

7

यदि आप वास्तव में एक ही परिणाम प्राप्त करने का मतलब है, तो उत्तर नहीं है।

कुछ मामलों में आपको उसी मशीन पर डीबग (गैर-अनुकूलित) बिल्ड बनाम रिलीज बिल्ड (अनुकूलित) के लिए अलग-अलग परिणाम भी मिल सकते हैं, इसलिए यह भी मानें कि परिणाम अलग-अलग मशीनों पर हमेशा समान हो सकते हैं।

(ऐसा हो सकता है जैसे इंटेल प्रोसेसर वाले कंप्यूटर पर, यदि ऑप्टिमाइज़र एक रजिस्टर में मध्यवर्ती परिणाम के लिए एक चर रखता है, जो अनियमित निर्माण में स्मृति में संग्रहीत होता है। चूंकि इंटेल एफपीयू रजिस्ट्रार 80 बिट हैं, और डबल चर 64 बिट हैं, इंटरमीडिएट परिणाम ऑप्टिमाइज्ड बिल्ड में अधिक सटीकता के साथ संग्रहीत किया जाएगा, जिसके बाद के परिणामों में अलग-अलग मान होंगे।)।

अभ्यास में, हालांकि, आप अक्सर एक ही परिणाम प्राप्त कर सकते हैं, लेकिन आपको उस पर भरोसा नहीं करना चाहिए।

1

सी # पर x86 पर, 80-बिट एफपी रजिस्टरों का उपयोग किया जाता है।

सी # मानक कहता है कि प्रोसेसर को स्वयं के प्रकार के समान परिशुद्धता पर काम करना चाहिए (यानी 'डबल' के मामले में 64-बिट)। भंडारण को छोड़कर, प्रचार की अनुमति है। इसका मतलब है कि स्थानीय और पैरामीटर 64-बिट परिशुद्धता से अधिक हो सकते हैं।

दूसरे शब्दों में, स्थानीय चर में एक सदस्य चर निर्दिष्ट करना (और वास्तव में कुछ परिस्थितियों में) असमानता देने के लिए पर्याप्त हो सकता है।

यह भी देखें: Float/double precision in debug/release modes

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