निम्नलिखित कोड:

    float numberForFactorial;
    float floatingPart = 1.400000;
    int integralPart = 1;

    numberForFactorial = ((floatingPart) - (float)integralPart) * 10;

    printf("%d", (int)numberForFactorial);

4 के बजाय 3 लौटाता है। क्या आप मुझे समझा सकते हैं कि क्यों?

1
Nikitas 30 अगस्त 2016, 21:53

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। गोलाई एक जटिल विषय है, इसलिए वह तरीका चुनें जिसकी बाधाएँ आपकी स्थिति से सबसे अच्छी तरह मेल खाती हों।

2
Mad Physicist 30 अगस्त 2016, 23:59

यह फ़्लोटिंग-पॉइंट मानों के द्विआधारी प्रतिनिधित्व के कारण है। अधिक विशेष रूप से, 0.4 या 2/5 को मंटिसा के साथ 1/2 + 1/4 + 1/8 + ... जैसे किसी भी संयोजन के योग के रूप में व्यक्त नहीं किया जा सकता है।

शाब्दिक 1.400000 को इसके द्विआधारी प्रतिनिधित्व में 1.399999976158142 के करीब कुछ के रूप में संग्रहीत किया जाता है। कास्ट int गैर-पूर्णांक भाग को काट देता है, अंतिम परिणाम के रूप में तीन देता है।

पांडित्यपूर्ण होने के लिए, सी मानक को फ़्लोटिंग-पॉइंट डेटा प्रकार के बाइनरी-आधारित प्रतिनिधित्व की आवश्यकता नहीं होती है, हालांकि आईईईई 754 वास्तव में आज की कंप्यूटिंग में स्टैंडड है।

2
Grzegorz Szpetkowski 30 अगस्त 2016, 22:13