निम्नलिखित कोड:
float numberForFactorial;
float floatingPart = 1.400000;
int integralPart = 1;
numberForFactorial = ((floatingPart) - (float)integralPart) * 10;
printf("%d", (int)numberForFactorial);
4 के बजाय 3 लौटाता है। क्या आप मुझे समझा सकते हैं कि क्यों?
2 जवाब
float
, 1.400000
के सबसे नजदीक 1.4
से थोड़ा कम है। आप इसे सत्यापित कर सकते हैं
printf("%0.8hf\n", floatingPart);
ideone का परिणाम 1.39999998
है। इसका मतलब है कि दशमलव बिंदु के बाद पहले अंक का 10 गुना 3
है।
इस समस्या से बचने के लिए ट्रंकेशन की जगह राउंडिंग का इस्तेमाल करें। गोल करने का एक आसान तरीका काट-छाँट से पहले आधा जोड़ना है:
printf("%d", (int)(numberForFactorial + 0.5f));
4
प्रिंट करेगा जैसा आप उम्मीद कर रहे थे। समान परिणाम प्राप्त करने के लिए आप round
, rint
, lround
, या modf
का भी उपयोग कर सकते हैं: https://www.gnu.org/software/libc/manual/html_node/Rounding-Functions.html। गोलाई एक जटिल विषय है, इसलिए वह तरीका चुनें जिसकी बाधाएँ आपकी स्थिति से सबसे अच्छी तरह मेल खाती हों।
यह फ़्लोटिंग-पॉइंट मानों के द्विआधारी प्रतिनिधित्व के कारण है। अधिक विशेष रूप से, 0.4
या 2/5
को मंटिसा के साथ 1/2 + 1/4 + 1/8 + ... जैसे किसी भी संयोजन के योग के रूप में व्यक्त नहीं किया जा सकता है।
शाब्दिक 1.400000
को इसके द्विआधारी प्रतिनिधित्व में 1.399999976158142
के करीब कुछ के रूप में संग्रहीत किया जाता है। कास्ट int
गैर-पूर्णांक भाग को काट देता है, अंतिम परिणाम के रूप में तीन देता है।
पांडित्यपूर्ण होने के लिए, सी मानक को फ़्लोटिंग-पॉइंट डेटा प्रकार के बाइनरी-आधारित प्रतिनिधित्व की आवश्यकता नहीं होती है, हालांकि आईईईई 754 वास्तव में आज की कंप्यूटिंग में स्टैंडड है।