2013-08-06 6 views
5

मैं प्रोग्रामिंग दुनिया के लिए नया हूँ और सी ++ पहले से ही मुझे खो रहा है। मैं अपने कार्यक्रम में इन पंक्तियों थापूर्णांक रूपांतरण - मुझे अजीब संख्या देता है

pennies=(amount-nickels*.05)/.01; 

राशि एक double है, जबकि और nickelsint हैं।

कार्यक्रम सही मान देता है जब पैसे एक double है, लेकिन चीजों को एक छोटे से बंद (बंद 1 से ज्यादातर समय) जब भी पैसे एक int है कर रहे हैं।

ऐसा क्यों हो रहा है?

+3

http://floating-point-gui.de –

+5

जब आप परिणाम 'पैनीज़' में संग्रहीत करते हैं, तो मूल्य गोलाकार के बजाय छोटा हो जाता है। 'Int pennies = 1.9 आज़माएं; std :: cout << पेनी; 'अपने लिए देखने के लिए। – jrok

+6

मुझे यकीन है कि लोग इस तरह के किसी मुद्दे के साथ मदद कर सकते हैं, लेकिन भविष्य में आपको उदाहरण डेटा शामिल करना चाहिए ताकि हम जान सकें कि "ऑफ" से आपका क्या मतलब है (उदाहरण के लिए "जब' राशि '10 है और 'निकल' 5 है मैं परिणाम 12 होने की उम्मीद करता हूं लेकिन यह 13 है। ") – JJJ

उत्तर

8

इसका कारण यह है मूल्य इस प्रकार दशमलव परिशुद्धता खोने छोटा किया गया है हो रहा है।

पूर्णांकों के लिए:

int i; 
i = 1.1 //stores 1 in i 
i = 1.2 //stores 1 in i 
i = 1.3 //stores 1 in i 
i = 1.4 //stores 1 in i 
i = 1.5 //stores 1 in i 
i = 1.6 //stores 1 in i 
i = 1.7 //stores 1 in i 
i = 1.8 //stores 1 in i 
i = 1.9 //stores 1 in i 
i = 1.999999 //stores 1 in i 

मैं करने के लिए अपने अभिव्यक्ति को बदलने के लिए आप सुझाव है:

pennies=amount*100-nickels*5; 
+2

नहीं, यह हो रहा है क्योंकि मान * गोल नहीं है। जैसा कि सवाल पर टिप्पणी में ज्रोक ने उल्लेख किया है, मूल्य कम हो जाता है। – hvd

+0

क्षमा करें, खराब अंग्रेजी – Saksham

+0

यह मध्यवर्ती गणनाओं में संख्यात्मक अपर्याप्तता के कारण भी हो सकता है, न केवल अंतिम परिणाम के दौर में। –

1

आप अभिव्यक्ति के अधिकार के हिस्से पर एक नाव संख्या की गणना, लेकिन तब आप स्टोर करने के लिए कोशिश एक int मूल्य में एक डबल। जब आप ऐसा करते हैं, तो fractional भाग खो जाता है।

3

के रूप में अन्य लोगों ने बताया है, समस्या क्योंकि 0.1 और 0.05 चल बिंदु मशीन में एक सटीक अभ्यावेदन नहीं है। यहाँ सबसे सरल समाधान के बजाय छोटा के लिए, बस परिणाम दौर के लिए है:

pennies = round((amount - nickels * 0.05)/0.01); 

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

  • double उपयोग करना जारी रखें, के रूप में आवश्यक गोलाई: इस तरह के मामलों के लिए, वहाँ दो संभव समाधान हैं। यह सरल और सबसे सामान्य समाधान है। सावधान रहें, हालांकि, इसका उपयोग करते समय, बाइनरी मानों पर गोलिंग किया जाता है, और कुछ मामलों में दशमलव मानों के साथ आपको क्या मिलेगा उससे भिन्न होता है। अंतर काफी छोटा है कि यह हर दिन के उपयोग के लिए कोई फर्क नहीं होगा होना चाहिए, लेकिन ज्यादातर देशों कानूनों को निर्दिष्ट कैसे इस तरह के मूल्यों गोल किया जाना चाहिए है, और उन गोलाई नियम हमेशा दशमलव में निर्दिष्ट हैं। जिसका अर्थ है कि यह समाधान उन मामलों में उपयोग नहीं किया जा सकता है जहां कानूनी आवश्यकताओं (उदाहरण के लिए बिक्री कर, कॉर्पोरेट बहीखाता इत्यादि की गणना) हो।

  • उपयोग दशमलव वर्ग किसी प्रकार का। नेटवर्क पर उपलब्ध नंबर उपलब्ध हैं। इसके परिणामस्वरूप धीमे निष्पादन के समय होंगे। (आमतौर पर, कौन परवाह करता है।आपको 10 के बजाय 100 माइक्रोसॉन्ड में परिणाम मिलेंगे लेकिन अपवाद हैं; जैसे जब मोंटे कार्लो सिमुलेशन

भी कर रही है।), जैसा कि आप जानते हैं जब बड़े मूल्यों शामिल कर रहे हैं होना चाहिए। आपके व्यक्तिगत वित्त के लिए, यह लगभग निश्चित रूप से अप्रासंगिक है, लेकिन int का अधिकतम मूल्य है, और एक बिंदु है जहां double अब पूर्णांक मानों का सही ढंग से प्रतिनिधित्व नहीं कर सकता है।

बेशक

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

और आपकी टिप्पणी के लिए "सी ++ पहले से ही मुझे खो रहा है": इसमें सी ++ प्रति से कोई लेना देना नहीं है। आपको लगभग किसी भी प्रोग्रामिंग भाषा में लगभग (लगभग) समस्याएं आती हैं।

1
    pennies=(amount-nickels*.05)/.01; 

ऊपर अभिव्यक्ति में, अंश और हर अंकगणित चर मात्रा की वजह से डबल में होता है (जो डबल है) - अंतर्निहित रूपांतरण यहाँ होता है। अंत में यदि पेनी डबल है तो गणना परिणाम पैनीज़ में संग्रहीत हो जाएगा, यदि यह int है, तो गणना किए गए परिणाम का आंशिक हिस्सा खो जाएगा। इंटरमीडिएट कंप्यूशन हमेशा डबल में होता है, और यह किसी भी तरह से पैनीज़ प्रकार पर निर्भर नहीं करता है।

उदाहरण

#include <stdio.h> 

int main() 
{ 

    int a ; 

    double c,d=10.55555; 

    a = c= (d+ 10*.5)/0.5 ; 
    printf("%f : %d/n",c,a); 
    return 0; 
} 

उत्पादन होता है:

31,111100: 31

यहाँ पहले 10 तो फ्लोट करने के लिए 10 * .5 का मूल्यांकन किया जाएगा बढ़ावा दिया जाता है, जो होगा दोहरे मूल्य के साथ जुड़ने के कारण दोहराया जाता है, तो denominator भी डबल में परिवर्तित हो जाता है क्योंकि संख्यात्मक डबल होता है, इसलिए कंप्यूशन ओसी केवल डबल प्रारूप में शाप दें।

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