2012-04-27 20 views
13

क्या कोई इस व्यवहार को समझा सकता है? मैं फ्लोटिंग पॉइंट नंबरों के मशीन-स्तरीय प्रतिनिधित्व के बारे में अच्छी तरह से अवगत हूं। ऐसा लगता है कि printf और इसके प्रारूपों से संबंधित है। दोनों संख्याओं को वास्तव में फ़्लोटिंग-पॉइंट नोटेशन द्वारा दर्शाया गया है (चेक: 64 से गुणा एक पूर्णांक देता है)।युगल के लिए प्रिंटफ राउंडिंग व्यवहार

#include <stdio.h> 
#include <iostream> 
using namespace std; 

int main() { 
    double x1=108.765625; 
    printf("%34.30f\n", x1); 
    printf("%9.5f\n", x1); 
    printf("%34.30f\n", x1*64); 

    double x2=108.046875; 
    printf("%34.30lf\n", x2); 
    printf("%9.5f\n", x2); 
    printf("%34.30f\n", x2*64); 
} 

आउटपुट:

> 108.765625000000000000000000000000 
> 108.76562 
> 6961.000000000000000000000000000000 
> 108.046875000000000000000000000000 
> 108.04688 
> 6915.000000000000000000000000000000 

ध्यान दें, पहली संख्या पूर्णांक हो जाता है, और दूसरा एक को गिरफ्तार किया जाता है।

+1

आपको मेरे लेख http://www.exploringbinary.com/inconsistent-rounding-of-printed-floating-point-numbers/ में रुचि हो सकती है। कुछ कार्यान्वयन "राउंड-आधा-से-यहां तक" के बजाय "राउंड-आधा-से-शून्य" का उपयोग करते हैं। –

+0

ऐसा प्रतीत होता है कि माइक्रोसॉफ्ट ने वीएस 2010 और वीएस2015 के बीच कुछ समय अपने डिफ़ॉल्ट गोलाकार व्यवहार को बदल दिया। मैंने बस एक से दूसरे में अपग्रेड किया और कुछ बहुत परेशान और सूक्ष्म बग मिला। [यह ब्लॉग] (https://blogs.msdn.microsoft.com/vcblog/2014/06/18/c-runtime-crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1 /) शायद परिवर्तन को हाइलाइट करने के लिए है, लेकिन इसे पूरी तरह से याद करने के लिए आपको क्षमा किया जाएगा। – omatai

+0

यह कार्यान्वयन पर निर्भर करता है [स्प्रिंटफ में विंडोज बनाम यूनिक्स आधारित सिस्टम पर राउंडिंग मतभेद] (http://stackoverflow.com/q/4649554/995714), [सी ++ स्प्रिंटफ के साथ संबंधों के लिए राउंडिंग व्यवहार स्थिरता] (http: // stackoverflow। कॉम/क्यू/31142600/995714) –

उत्तर

17

यह "राउंड आधे से भी" या "बैंकर राउंडिंग" है। गोलाकार प्रतिनिधित्व का अंतिम अंक तब भी चुना जाता है जब संख्या दोनों के बीच बिल्कुल आधा रास्ता हो।

http://linuxgazette.net/144/misc/lg/a_question_of_rounding_in_issue_143.html:
बैंकरों गोलाई "या" दौर भी करने के लिए "यह कुछ अन्य सी पुस्तकालयों की तुलना में अधिक सही है, के रूप में C99 विनिर्देश कहते हैं," GNU सी पुस्तकालय के लिए, राउंडिंग) printf द्वारा इस्तेमाल किया (नियम है। " दशमलव में रूपांतरण वर्तमान में चयनित आईईईई राउंडिंग मोड (डिफ़ॉल्ट बैंकर राउंडिंग) का उपयोग करना चाहिए। "

+0

भी: http://www.gnu.org/software/libc/manual/html_node/Rounding.html –

+1

लिंक किए गए आलेख का लेखक अक्षम है। "बाइनरी और दशमलव रेडिक्स अजीब संख्याओं के एक ही सेट को साझा नहीं करते हैं" - यह बकवास है। तर्कसंगतता/तर्कहीनता आधार से स्वतंत्र है। –

+1

@ आर .. दरअसल। लेकिन लेख का उद्धृत मार्ग सही है, क्योंकि लेखक ने अपनी [बग रिपोर्ट] (http://sourceware.org/bugzilla/show_bug.cgi?id=4943) में दर्द से सीखा। –

0

%9.5f आउटपुट दशमलव संख्या के बाद 5 अंकों के साथ संख्या देता है जो स्रोत संख्या के निकटतम है।