क्या मुझे डबल या फ्लोट का उपयोग करना चाहिए?


89

C ++ में दूसरे के बजाय एक का उपयोग करने के फायदे और नुकसान क्या हैं?


क्या किसी ने फ्लोट्स की एक सरणी और डबल्स की एक सरणी बनाने की कोशिश की है और देखें कि क्या वास्तव में फ्लोट्स पर सदस्यों के बीच 4 बाइट्स और डबल्स पर सदस्यों के बीच 8 बाइट्स हैं? यह संभव है कि 64 बिट कंपाइलर / कंप्यूटर अभी भी फ़्लोट्स के लिए प्रति सदस्य 8 बाइट्स आरक्षित कर सकते हैं, भले ही उन्हें उतनी ज़रूरत न हो।
user3015682

जवाबों:


104

अगर आप इसका सही जवाब जानना चाहते हैं, तो आपको फ्लोटिंग-पॉइंट अरिथमेटिक के बारे में हर कंप्यूटर साइंटिस्ट को पता होना चाहिए

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

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


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

5
खैर SSE (या कोई भी वर्टिकल फ्लोटिंग पॉइंट यूनिट) डबल परिशुद्धता की तुलना में एकल परिशुद्धता में फ्लॉप की संख्या को दोगुना करने में सक्षम होगा। यदि आप सिर्फ x87 (या कोई स्केलर) फ्लोटिंग पॉइंट कर रहे हैं तो यह संभवत: कोई मायने नहीं रखेगा।
ग्रेग रोजर्स

1
@Greg रोजर्स: कंपाइलर इस समय स्मार्ट नहीं हैं। जब तक आप कच्ची असेंबली नहीं लिख रहे हैं, तब तक यह अलग नहीं है। और हां, यह बदल सकता है क्योंकि कंपाइलर विकसित होता है।
J-16 SDiZ

एक अतिरिक्त नोट: यदि आपके पास कोई पता नहीं है कि डेटा कैसा दिखता है (या लिंक में सभी गणित में कोई सुराग नहीं है), तो बस उपयोग करें double- यह ज्यादातर मामलों में सुरक्षित है।
J-16 SDiZ

2
यह पेपर छोटा नहीं है।
जोकुन डेस

44

जब तक आपके पास अन्यथा करने के लिए कुछ विशिष्ट कारण न हों, दोहरे का उपयोग करें।

शायद आश्चर्यजनक रूप से, यह डबल है और फ्लोट नहीं है जो कि सी (और सी ++) में "सामान्य" फ्लोटिंग-पॉइंट प्रकार है। मानक गणित कार्य जैसे कि पाप और लॉग डबल्स को तर्क के रूप में लेते हैं, और डबल्स को वापस लौटाते हैं। एक सामान्य फ्लोटिंग-पॉइंट शाब्दिक, जब आप अपने प्रोग्राम में 3.14 लिखते हैं , तो टाइप डबल होता है। तैरता नहीं।

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


26

इस सवाल का जवाब देना असंभव है क्योंकि सवाल का कोई संदर्भ नहीं है। यहाँ कुछ चीजें हैं जो पसंद को प्रभावित कर सकती हैं:

  1. फ्लोट, डबल्स और लॉन्ग डबल्स का कंपाइलर कार्यान्वयन। C ++ मानक स्थिति:

    तीन फ्लोटिंग पॉइंट प्रकार होते हैं: फ्लोट, डबल और लॉन्ग डबल। टाइप डबल कम से कम उतनी सटीकता प्रदान करता है जितना फ्लोट, और टाइप डबल डबल कम से कम उतना सटीक प्रदान करता है जितना डबल।

    तो, स्मृति में तीनों एक ही आकार के हो सकते हैं।

  2. एक FPU की उपस्थिति। सभी CPU में FPU नहीं होते हैं और कभी-कभी फ़्लोटिंग पॉइंट प्रकार का अनुकरण किया जाता है और कभी-कभी फ़्लोटिंग पॉइंट प्रकार का समर्थन नहीं किया जाता है।

  3. FPU वास्तुकला। IA32 का एफपीयू आंतरिक रूप से 80 बिट है - 32 बिट और 64 बिट फ्लोट को लोड पर 80bit तक विस्तारित किया जाता है और स्टोर पर कम किया जाता है। वहाँ भी SIMD है जो चार 32bit फ़्लोट या दो 64bit फ़्लोट समानांतर में कर सकते हैं। SIMD का उपयोग मानक में परिभाषित नहीं किया जाता है, इसलिए इसे एक कंपाइलर की आवश्यकता होती है जो यह निर्धारित करने के लिए अधिक जटिल विश्लेषण करता है कि क्या SIMD का उपयोग किया जा सकता है, या विशेष कार्यों (पुस्तकालयों या आंतरिक) के उपयोग की आवश्यकता होती है। 80 बिट आंतरिक प्रारूप का अपशॉट यह है कि आप कितनी बार डेटा को रैम में सहेजा जाता है (इस प्रकार, सटीकता खोना) के आधार पर थोड़ा अलग परिणाम प्राप्त कर सकते हैं। इस कारण से, कंपाइलर्स फ्लोटिंग पॉइंट कोड को विशेष रूप से अच्छी तरह से ऑप्टिमाइज़ नहीं करते हैं।

  4. मेमोरी बैंडविड्थ। यदि एक फ्लोट की तुलना में डबल को अधिक भंडारण की आवश्यकता होती है, तो डेटा को पढ़ने में अधिक समय लगेगा। वह भोला जवाब है। आधुनिक IA32 पर, यह सब इस बात पर निर्भर करता है कि डेटा कहां से आ रहा है। यदि यह L1 कैश में है, तो लोड नगण्य है, बशर्ते डेटा एकल कैश लाइन से आता है। यदि यह एक से अधिक कैश लाइन में फैला है तो एक छोटा ओवरहेड है। यदि यह L2 से है, तो इसे थोड़ी देर लगती है, यदि यह RAM में है तो यह अभी भी और अंत में है, यदि यह डिस्क पर है तो यह बहुत बड़ा समय है। तो फ्लोट या डबल का चुनाव डेटा के उपयोग के तरीके से कम महत्वपूर्ण नहीं है। यदि आप बहुत सारे अनुक्रमिक डेटा पर एक छोटी गणना करना चाहते हैं, तो एक छोटा डेटा प्रकार बेहतर है। एक छोटे डेटा सेट पर बहुत अधिक गणना करने से आप किसी भी महत्वपूर्ण प्रभाव के साथ बड़े डेटा प्रकारों का उपयोग कर सकते हैं। अगर तुम' डेटा को बहुत बेतरतीब ढंग से एक्सेस करना, फिर डेटा साइज़ का चुनाव महत्वहीन है - डेटा पेज / कैश लाइनों में लोड होता है। इसलिए यदि आप केवल रैम से एक बाइट चाहते हैं, तो आप 32 बाइट्स स्थानांतरित कर सकते हैं (यह सिस्टम की वास्तुकला पर बहुत निर्भर है)। इस सब के ऊपर, सीपीयू / एफपीयू सुपर-स्केलर (उर्फ पाइपलाइड) हो सकता है। इसलिए, भले ही एक लोड कई चक्र ले सकता है, सीपीयू / एफपीयू कुछ और (उदाहरण के लिए एक गुणा) करने में व्यस्त हो सकता है जो लोड समय को एक हद तक छुपाता है।

  5. मानक अस्थायी बिंदु मानों के लिए किसी विशेष प्रारूप को लागू नहीं करता है।

यदि आपके पास एक विनिर्देश है, तो यह आपको इष्टतम विकल्प के लिए मार्गदर्शन करेगा। अन्यथा, यह अनुभव करना है कि क्या उपयोग करना है।


16

डबल अधिक सटीक है लेकिन 8 बाइट्स पर कोडित है। फ्लोट केवल 4 बाइट्स है, इसलिए कम कमरा और कम परिशुद्धता।

यदि आपके पास अपने आवेदन में डबल और फ्लोट है तो आपको बहुत सावधान रहना चाहिए। मेरे पास अतीत में होने के कारण एक बग था। कोड का एक हिस्सा फ्लोट का उपयोग कर रहा था जबकि बाकी कोड डबल का उपयोग कर रहा था। डबल को फ्लोट करने के लिए कॉपी करना और फिर डबल से फ्लोट करना सटीक त्रुटि का कारण बन सकता है जो बड़ा प्रभाव डाल सकता है। मेरे मामले में, यह एक रासायनिक कारखाना था ... उम्मीद है कि यह नाटकीय परिणाम नहीं था :)

मुझे लगता है कि यह इस तरह के बग के कारण है कि एरियन 6 रॉकेट कुछ साल पहले फट गया है !!!

एक चर के लिए उपयोग किए जाने वाले प्रकार के बारे में ध्यान से सोचें


3
ध्यान दें कि फ्लोट / डबल के लिए 4/8 बॉट की भी गारंटी नहीं है, यह प्लेटफॉर्म पर निर्भर करेगा। यह उसी प्रकार का भी हो सकता है ...
sleske

2
एरियन -5 कोड एक 16 बिट के साइन्ड इंटीजर में एक 64 बिट चल बिन्दु, जिसकी कीमत 32,767 से अधिक थी, कन्वर्ट करने के लिए कोशिश की। इसने एक अतिप्रवाह अपवाद उत्पन्न किया जिसके कारण रॉकेट ने अपने आत्म-विनाश के क्रम को शुरू किया। प्रश्न में कोड, एक पुराने, छोटे रॉकेट से पुन: उपयोग किया गया कोड था।
cmwt

5

जब तक मैं कुछ अड़चनों को नहीं देख लेता, मैं हर समय दोहरी मार करता हूं। फिर मैं किसी अन्य भाग को तैरने या अनुकूलन करने के लिए आगे बढ़ना मानता हूं


4

यह इस बात पर निर्भर करता है कि संकलक दोहरे कैसे करता है। यह डबल और फ्लोट के लिए एक ही प्रकार का कानूनी है (और यह कुछ प्रणालियों पर है)।

कहा जा रहा है, अगर वे वास्तव में अलग हैं, मुख्य मुद्दा सटीक है। आकार में अंतर होने के कारण एक डबल में बहुत अधिक सटीकता होती है। यदि आपके द्वारा उपयोग किए जा रहे नंबर सामान्य रूप से फ्लोट के मान से अधिक होंगे, तो एक डबल का उपयोग करें।

कई अन्य लोगों ने प्रदर्शन का उल्लेख किया है। यह मेरे विचारों की सूची पर बिल्कुल अंतिम होगा। सुधार आपके # 1 विचार होना चाहिए।


3

उचित परिणाम प्राप्त करने के लिए जो भी सटीक हो, का उपयोग करें । अगर आपको पता चलता है कि आपका कोड उतना अच्छा प्रदर्शन नहीं कर रहा है, जितना आप चाहते हैं (आपने सही प्रोफाइलिंग का उपयोग किया है?) पर एक नज़र डालें:


2

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



1

यह सीपीयू पर अत्यधिक निर्भर करता है सटीक और मेमोरी के बीच सबसे स्पष्ट ट्रेड-ऑफ हैं। GB की RAM के साथ, मेमोरी कोई समस्या नहीं है, इसलिए आमतौर पर इसका उपयोग करना बेहतर होता हैdouble s ।

प्रदर्शन के लिए, यह CPU पर अत्यधिक निर्भर करता है। floats आमतौर doubleपर 32 बिट मशीन पर s की तुलना में बेहतर प्रदर्शन प्राप्त करेगा । 64 बिट पर, doubleएस कभी-कभी तेज होते हैं, क्योंकि यह (आमतौर पर) मूल आकार होता है। फिर भी, डेटा प्रकारों की आपकी पसंद से बहुत अधिक क्या मायने रखता है या नहीं, आप अपने प्रोसेसर पर SIMD के निर्देशों का लाभ उठा सकते हैं या नहीं।


0

डबल में उच्च परिशुद्धता होती है, जबकि फ्लोट कम मेमोरी लेते हैं और तेज होते हैं। सामान्य तौर पर आपको फ्लोट का उपयोग करना चाहिए जब तक कि आपके पास ऐसा मामला न हो जहां यह पर्याप्त सटीक न हो।


5
विशिष्ट आधुनिक कंप्यूटरों पर, डबल फ्लोट के समान ही तेज़ है।
थॉमस पैड्रॉन-मैक्कार्थी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.