2012-03-01 8 views
6

मैंने अपेक्षाकृत सरल एल्गोरिदम परिवर्तित किया है जो double की संख्याओं पर सी ++ से जावा तक की संख्याओं पर बड़ी संख्या में गणना करता है, हालांकि दो प्लेटफार्मों पर एल्गोरिदम चला रहा है लेकिन एक ही मशीन थोड़ा अलग परिणाम उत्पन्न करती है। एल्गोरिदम गुणा करता है और बहुत सारे युगल और स्याही का योग करता है। मैं जावा एल्गोरिदम में डबल करने के लिए इन्स कास्टिंग कर रहा हूँ; सी एल्गोरिदम नहीं डाला जाता है।फ़्लोटिंग पॉइंट हैंडलिंग में मतभेदों के कारण अलग-अलग परिणाम क्या हैं इसकी पुष्टि कैसे करें?

  • (जावा) 64,684,970
  • (C++) 65296408

(अनदेखी करने के लिए मुद्रित दशमलव स्थानों)

स्वाभाविक रूप से:

उदाहरण के लिए, एक रन पर मैं परिणाम प्राप्त , मेरे एल्गोरिदम में कोई त्रुटि हो सकती है, हालांकि इससे पहले कि मैं समय डिबगिंग खर्च करना शुरू कर दूं, क्या यह संभव है कि सी ++ और जा में विभिन्न फ़्लोटिंग पॉइंट हैंडलिंग द्वारा अंतर समझाया जा सके va? यदि हां, तो क्या मैं साबित कर सकता हूं कि यह समस्या है?


अद्यतन - जिस स्थान पर भिन्नता है, वह दो चींटियों के बीच एक गुणा है जो तब चलने वाले कुल डबल में जोड़ा जाता है। सी कोड को संशोधित करने के बाद, वर्तमान में दोनों में:

mydouble += (double)int1 * (double)int2

+0

जावा संस्करण में आपने किस डेटा प्रकार का उपयोग किया था? – wallyk

+4

यह काफी अंतर है, और मुझे संदेह है कि गोल-ऑफ त्रुटियों के कारण हो सकता है। मेरा अनुमान है कि आपने कहीं गलती की है। जब तक आप 1E300 और सामान द्वारा विभाजित करने जैसी काफी चरम चीजें नहीं करते हैं। –

+0

@ वैलीक: डबल। – Brabster

उत्तर

2

AFAIK वहाँ बार जब एक डबल शाब्दिक का मूल्य दो सी ++ संकलक संस्करणों के बीच बदल सकता हैं (जब एल्गोरिदम स्रोत को अगले सर्वोत्तम डबल मान में परिवर्तित करने के लिए उपयोग किया जाता है)।

कुछ सीपीयू फ्लोटिंग पॉइंट रजिस्टरों पर भी 64/32 बिट (अधिक रेंज और परिशुद्धता) से बड़ा है, और यह परिणाम कैसे प्रभावित करता है इस पर निर्भर करता है कि कंपाइलर और जेआईटी इन रजिस्टरों में से और बाहर मूल्य कैसे लेते हैं - यह संभव है जावा और सी ++ के बीच भिन्न है।

जावा में यह सुनिश्चित करने के लिए सख्ती से कीवर्ड है कि केवल 64/32 बिट परिशुद्धता का उपयोग किया जाता है, हालांकि यह रन-टाइम लागत के साथ आता है। आईईईई मानक द्वारा किए गए गारंटी/नियमों को फेंक कर सी ++ कंपाइलर्स फ्लोटिंग पॉइंट कंप्यूटेशंस का इलाज और अनुकूलन कैसे प्रभावित करते हैं, इस पर प्रभाव डालने के लिए बड़ी संख्या में विकल्प भी हैं।

यदि एल्गोरिदम अधिकतर समान है तो आप जांच सकते हैं कि एक ही इनपुट के लिए पहला अंतर कहां दिखाई देता है।

+0

इस मामले में चरण-दर-चरण आउटपुट की जांच अलग-अलग चरण की पहचान की और मुझे डेटा में एक अंतर के लिए इंगित किया। यह सुधारने के बाद कि एल्गोरिदम सहमत हैं। – Brabster

3

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

+0

जब तक मैं कुछ याद नहीं कर रहा हूं, गोल करने से समस्या की संख्या कम हो सकती है, लेकिन यह सभी समस्याओं को खत्म नहीं करेगा? मुझे लगता है कि आप अभी भी कम सटीक गोलाकार फ्लोट में एक सटीक अंतर डाल सकते हैं, मुझे लगता है? जैसे कि सीपीयू पर 95.4 99 99 99 4 9 देता है और दूसरा 95.4 99 99 99 5 देता है और आप उस परिशुद्धता पर गोल करते हैं, तो आपको कम दशमलव के बावजूद अलग-अलग मूल्य मिलेंगे? –

1

जावा में, 64-बिट फ़्लोटिंग- बिंदु संख्या। सी ++ में, डबल एक फ्लोटिंग-पॉइंट नंबर है जो कम से कम 32-बिट सटीक होने की गारंटी देता है।

वास्तविक आकार का पता लगाने के लिए, अपने सिस्टम पर एक सी ++ डबल के बाइट्स में, आकार (डबल) का उपयोग करें।

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

(तकनीकी तौर पर, एक बाइट का आकार मंच पर निर्भर है, लेकिन सबसे आधुनिक आर्किटेक्चर 8 बिट बाइट का उपयोग करें।)

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