c# - क्या फ्लोटिंग पॉइंट अंकगणितीय स्थिर है?




floating-point (4)

इस सवाल का पहले से ही यहाँ एक जवाब है:

मुझे पता है कि फ्लोटिंग पॉइंट नंबरों में सटीक है और सटीक के बाद अंक विश्वसनीय नहीं है।

लेकिन क्या होगा यदि संख्या की गणना करने के लिए उपयोग किया जाने वाला समीकरण समान हो? क्या मैं मान सकता हूं कि परिणाम भी वही होगा?

उदाहरण के लिए हमारे पास दो फ्लोट संख्या है x और y । क्या हम मान सकते हैं कि मशीन 1 से परिणाम x/y मशीन 2 से परिणाम के समान है? IE == तुलना सच होगी


लेकिन क्या होगा यदि संख्या की गणना करने के लिए उपयोग किया जाने वाला समीकरण समान हो? क्या मैं मान सकता हूं कि परिणाम भी वही होगा?

नहीं, जरूरी नहीं।

विशेष रूप से, कुछ स्थितियों में JIT को अधिक सटीक मध्यवर्ती प्रतिनिधित्व का उपयोग करने की अनुमति है - उदाहरण के लिए 80 बिट्स जब आपका मूल डेटा 64 बिट्स है - जबकि अन्य स्थितियों में यह नहीं होगा। निम्नलिखित में से कोई भी सत्य होने पर विभिन्न परिणाम देखने को मिल सकते हैं:

  • आपके पास थोड़ा अलग कोड है, उदाहरण के लिए एक फ़ील्ड के बजाय एक स्थानीय चर का उपयोग करना, जो यह बदल सकता है कि मूल्य एक रजिस्टर में संग्रहीत है या नहीं। (यह एक अपेक्षाकृत स्पष्ट उदाहरण है; अन्य बहुत अधिक सूक्ष्म हैं जो चीजों को प्रभावित कर सकते हैं, जैसे कि विधि में एक try ब्लॉक का अस्तित्व ...)
  • आप एक अलग प्रोसेसर पर काम कर रहे हैं (मैं AMD और Intel के बीच अंतर का निरीक्षण करता था; एक ही निर्माता से अलग CPU के बीच अंतर हो सकता है)
  • आप अलग-अलग अनुकूलन स्तरों के साथ क्रियान्वित कर रहे हैं (जैसे डिबगर के तहत या नहीं)

C # 5 विनिर्देशन अनुभाग 4.1.6 से:

फ्लोटिंग-पॉइंट ऑपरेशन को ऑपरेशन के परिणाम प्रकार की तुलना में उच्च परिशुद्धता के साथ किया जा सकता है। उदाहरण के लिए, कुछ हार्डवेयर आर्किटेक्चर एक "विस्तारित" या "लॉन्ग डबल" फ्लोटिंग-पॉइंट प्रकार का समर्थन करते हैं, जिसमें डबल रेंज की तुलना में अधिक रेंज और सटीक होता है, और इस उच्च परिशुद्धता प्रकार का उपयोग करते हुए सभी फ्लोटिंग-पॉइंट ऑपरेशन करते हैं। केवल प्रदर्शन में अत्यधिक लागत पर ऐसे हार्डवेयर आर्किटेक्चर को कम सटीकता के साथ फ्लोटिंग-पॉइंट ऑपरेशन करने के लिए बनाया जा सकता है और इसके बजाय प्रदर्शन और परिशुद्धता दोनों को लागू करने के लिए कार्यान्वयन की आवश्यकता होती है, C # सभी फ़्लोटिंग पॉइंट ऑपरेशन के लिए एक उच्च परिशुद्धता प्रकार का उपयोग करने की अनुमति देता है । अधिक सटीक परिणाम देने के अलावा, इसका शायद ही कोई औसत दर्जे का प्रभाव हो। हालाँकि, प्रपत्र x * y / z अभिव्यक्तियों में, जहाँ गुणन एक परिणाम उत्पन्न करता है जो दोहरी सीमा के बाहर होता है, लेकिन बाद में विभाजन अस्थायी परिणाम को दोहरी सीमा में वापस लाता है, इस तथ्य का कि उच्चतर में मूल्यांकन किया जाता है सीमा प्रारूप एक अनंत के बजाय एक परिमित परिणाम उत्पन्न कर सकता है।


अन्य उत्तरों के अलावा, यह एक ही मशीन पर भी संभव x/y != x/y

X86 में फ़्लोटिंग-पॉइंट कंप्यूटेशन 80-बिट रजिस्टरों का उपयोग करके किया जाता है, लेकिन संग्रहीत होने पर 64-बिट्स तक छोटा हो जाता है। इसलिए यह संभव है कि पहले डिवीजन की गणना, काट-छाँट की जाए, फिर मेमोरी में वापस लोड किया जाए और गैर-ट्रेंकुलेटेड डिवीजन के मुकाबले तुलना की जाए।

अधिक जानकारी के लिए here देखें (यह C ++ लिंक है, लेकिन तर्क समान है)


नहीं, यह नहीं है। गणना का परिणाम प्रति सीपीयू अलग-अलग हो सकता है, क्योंकि फ्लोटिंग प्वाइंट अंकगणितीय का कार्यान्वयन सीपीयू निर्माता या सीपीयू डिजाइन के अनुसार भिन्न हो सकता है। मुझे कुछ इंटेल प्रोसेसर में फ्लोटिंग पॉइंट अंकगणित में एक बग भी याद है, जिसने हमारी गणना को खराब कर दिया।

और फिर अंतर यह है कि कोड का मूल्यांकन कैसे किया जाता है JIT कंपाइलर।


सच कहूँ तो मुझे एक ही कोडबेस में दो जगह की उम्मीद नहीं है कि एक ही x और y लिए एक ही चीज़ को एक ही x और y - एक ही मशीन पर एक ही प्रक्रिया में; यह इस बात पर निर्भर कर सकता है कि कंपाइलर / JIT द्वारा x और y को वास्तव में कैसे अनुकूलित किया जाता है - यदि उन्हें अलग-अलग तरीके से अपंजीकृत किया जाता है, तो उनके अलग-अलग मध्यवर्ती उदाहरण हो सकते हैं। आपकी अपेक्षा (रजिस्टर आकार) से अधिक बिट्स का उपयोग करके बहुत सारे ऑपरेशन किए जाते हैं; और जब यह 64 बिट्स के लिए मजबूर हो जाता है तो परिणाम को प्रभावित कर सकता है। उस "बिल्कुल जब" का विकल्प आसपास के कोड में और क्या हो रहा है, इस पर निर्भर करता है।







floating-point