2010-10-25 7 views
10

मैं प्लेटफ़ॉर्म लक्ष्य x64 और x86 के साथ .NET 2.0 का उपयोग कर रहा हूं। मैं गणित दे रहा हूं। एक ही इनपुट नंबर का विस्तार करें, और यह किसी भी मंच में अलग-अलग परिणाम देता है।मैथ.एक्सपी 32-बिट और 64-बिट के बीच अलग-अलग परिणाम देता है, उसी इनपुट के साथ, उसी हार्डवेयर

MSDN कहते हैं आप प्लेटफार्मों के बीच एक ही नंबर का प्रतिनिधित्व करने के एक शाब्दिक/पार्स डबल पर भरोसा नहीं कर सकते हैं, लेकिन मुझे लगता है कि Int64BitsToDouble के अपने प्रयोग के नीचे इस समस्या से बचा जाता है और दोनों प्लेटफार्मों पर Math.Exp को एक ही इनपुट गारंटी देता है।

मेरा प्रश्न यह है कि परिणाम अलग क्यों हैं? मैं सोचा होगा कि:

  • इनपुट एक ही तरीके से संग्रहीत किया जाता है (डबल/64-बिट परिशुद्धता)
  • एफपीयू प्रोसेसर की bitness
  • उत्पादन में संग्रहित है की परवाह किए बिना एक ही गणना करना होगा वैसे ही

मुझे पता है कि मुझे सामान्य रूप से 15/17 वें अंकों के बाद फ्लोटिंग-पॉइंट नंबरों की तुलना नहीं करनी चाहिए, लेकिन मैं उसी हार्डवेयर पर एक ही ऑपरेशन की तरह दिखने के साथ असंगतता के बारे में उलझन में हूं।

कोई भी जानता है कि हुड के नीचे क्या चल रहा है?

double d = BitConverter.Int64BitsToDouble(-4648784593573222648L); // same as Double.Parse("-0.0068846153846153849") but with no concern about losing digits in conversion 
Debug.Assert(d.ToString("G17") == "-0.0068846153846153849" 
    && BitConverter.DoubleToInt64Bits(d) == -4648784593573222648L); // true on both 32 & 64 bit 

double exp = Math.Exp(d); 

Console.WriteLine("{0:G17} = {1}", exp, BitConverter.DoubleToInt64Bits(exp)); 
// 64-bit: 0.99313902928727449 = 4607120620669726947 
// 32-bit: 0.9931390292872746 = 4607120620669726948 

परिणाम जेआईटी चालू या बंद दोनों प्लेटफ़ॉर्म पर संगत हैं।

[संपादित करें]

मैं पूरी तरह से तो यहाँ नीचे दिए गए उत्तर से संतुष्ट नहीं कर रहा हूँ मेरी खोज से कुछ और जानकारी कर रहे हैं।

http://www.manicai.net/comp/debugging/fpudiff/ का कहना है कि:

तो 32-बिट 80-बिट एफपीयू रजिस्टरों उपयोग कर रहा है, 64-बिट 128 बिट SSE उपयोग कर रहा है पंजीकृत करता है।

और CLI स्टैंडर्ड कहते हार्डवेयर इसका समर्थन करता है, तो यह है कि युगल उच्च परिशुद्धता के साथ किया जा सकता है:

[दलील: इस डिजाइन CLI के लिए एक मंच-विशिष्ट उच्च प्रदर्शन प्रतिनिधित्व चुनने की अनुमति देता फ़्लोटिंग-पॉइंट संख्याएं जब तक उन्हें संग्रहण स्थानों में रखा न जाए। उदाहरण के लिए, यह हार्डवेयर रजिस्टरों में फ़्लोटिंग-पॉइंट चर छोड़ने में सक्षम हो सकता है जो उपयोगकर्ता द्वारा अनुरोध किए गए अधिक सटीकता प्रदान करते हैं। विभाजन I 69 एक ही समय में, सीआईएल जेनरेटर के माध्यम से रूपांतरण निर्देशों के उपयोग के माध्यम से प्रतिनिधित्व के लिए भाषा-विशिष्ट नियमों का सम्मान करने के लिए संचालन को मजबूर कर सकते हैं। अंत औचित्य]

http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-335.pdf (फ्लोटिंग प्वाइंट डेटा प्रकार के 12.1.3 हैंडलिंग)

मुझे लगता है कि यह यहाँ क्या हो रहा है, क्योंकि परिणाम परिशुद्धता के डबल के मानक 15 अंक के बाद अलग। 64-बिट Math.Exp परिणाम अधिक सटीक है (इसमें एक अतिरिक्त अंक है) क्योंकि आंतरिक रूप से 64-बिट .NET 32-बिट .NET द्वारा उपयोग किए गए एफपीयू रजिस्टर की तुलना में अधिक सटीकता के साथ एक एफपीयू रजिस्टर का उपयोग कर रहा है।

+0

+1 दिलचस्प। मैं अपनी मशीन पर सटीक वही लक्षण देखता हूं, और x86/anycpu के बीच स्विचिंग आउटपुट को बदलता है। – sisve

+1

आपका अंतिम अनुच्छेद गलत है। 32-बिट संस्करण ** अधिक सही ** होगा क्योंकि यह 80-बिट विस्तारित सटीक x87 एफपीयू का उपयोग करता है, जबकि 64-बिट संस्करण तेज़ और अधिक संगत एसएसई 2 का उपयोग करेगा। –

+1

संभावित डुप्लिकेट [x86 और x64 के बीच फ़्लोटिंग पॉइंट अंकगणित में अंतर] (http://stackoverflow.com/questions/22710272/difference-in-floating-point-arithmetics-between-x86-and-x64) –

उत्तर

3

हां राउंडिंग त्रुटियां, और यह प्रभावी रूप से वही हार्डवेयर नहीं है। 32 बिट संस्करण निर्देशों के एक अलग सेट को लक्षित कर रहा है और आकार पंजीकृत कर रहा है।

+1

यह दिलचस्प है - क्या आप कह रहे हैं कि एफपीयू निर्देशों का एक अलग सेट है? माना जाता है कि मुझे नहीं पता कि कैसे Math.Exp लागू किया गया है, चाहे वह एक एफपीयू निर्देश है या कई। और मैंने सोचा होगा कि एफपीयू रजिस्ट्रार दोनों प्लेटफ़ॉर्म में समान हैं क्योंकि मैं 'डबल' प्रकार का उपयोग कर रहा हूं। – Yoshi

+0

मुझे .NET कार्यान्वयन या x64 fpu के minutae को नहीं पता, लेकिन मुझे उम्मीद नहीं थी कि वे समान हों। आप int से डबल में भी परिवर्तित हो रहे हैं जो एक त्रुटि पेश कर रहा है। – winwaed

+1

मैं इसे उत्तर के रूप में चिह्नित करने जा रहा हूं क्योंकि मुझे लगता है कि यह सबसे अधिक जानकारी प्रदान करता है। मुझे इस यूआरएल पर अधिक जानकारी मिली, जो बताती है कि 32-बिट .NET 80-बिट एफपीयू रजिस्टरों का उपयोग कर रहा है, और 64-बिट .NET 128-बिट एसएसई रजिस्टरों का उपयोग कर रहा है: http://www.manicai.net/comp/ डीबगिंग/fpudiff/ – Yoshi

3
डबल प्रकार आप राउंडिंग त्रुटियों मिलेगा, बाइनरी में अंशों बहुत जल्दी बहुत बड़ी पाने के रूप में साथ

। यदि आप दशमलव प्रकार का उपयोग करते हैं तो यह संभवतः मदद करेगा।

+0

I (सोचो) मैं समझता हूं, लेकिन एक ही हार्डवेयर पर एक ही इनपुट पर समान गणना पर होने वाली किसी भी गोल करने वाली त्रुटियां लीज़ पर होनी चाहिए टी सुसंगत नहीं है, है ना? या इसके कुछ अन्य कारकों के कारण इसकी कोई गारंटी नहीं है? – Yoshi

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

  • कोई संबंधित समस्या नहीं^_^