printf

2012-04-01 17 views
14

के साथ फ्लोट की प्रेसिजन सभी जानते हैं कि float के मान को आउटपुट करने के लिए आप printf का उपयोग करते समय सीमित परिशुद्धता रखते हैं।
हालांकि, वहाँ उत्पादन में शुद्धता को बढ़ाने के लिए एक चाल है, के रूप में इस उदाहरण दिखाता है:printf

#include <stdio.h> 

int main() 
{ 
    float f = 1318926965;  /* 10 random digits */ 
    printf("%10.f\n", f);  /* prints only 8 correct digits */ 
    printf("%10d\n", *(int*)&f); /* prints all digits correctly */ 
    return 0; 
} 

और मेरे सवाल का, यही कारण है कि लोगों को और अधिक अक्सर इस चाल का उपयोग नहीं करते?

+1

क्योंकि संभावित रूप से अपरिभाषित व्यवहार खराब है। (संपादित करें: तकनीकी रूप से यह अपरिभाषित व्यवहार नहीं हो सकता है, क्योंकि मुझे यकीन नहीं है कि मानक इसके बारे में क्या कहता है। अंतहीनता आपको इसके साथ काट सकती है।) – Corbin

+8

+1 अप्रैल के पहले मजाक के लिए +1! – Henrik

+0

यह स्पष्ट रूप से मुझे x.x – Corbin

उत्तर

11

अप्रैल मूर्ख?

आपका "यादृच्छिक संख्या" 1318926965 दशमलव और फ़्लोटिंग-पॉइंट फॉर्म दोनों में समान अंतर्निहित प्रतिनिधित्व है।

10 की तरह एक और मूल्य प्रयास करें।

 10 
1092616192 

तो अपने सवाल का जवाब देने: के रूप में यह प्रिंट होगा

and my question is, why don't people use this trick more often? 

क्योंकि वर्ष के केवल एक दिन अप्रैल फूल्स डे ... दिनों के आराम के चाल से काम नहीं करता है ...

4

, एक अलग संख्या के साथ कि एक ही चाल का प्रयास कहना 2318926965.

#include <stdio.h> 

int main() 
{ 
    float f = 2318926965;  /* 10 random digits */ 
    printf("%10.f\n", f);  /* prints only 8 correct digits */ 
    printf("%10d\n", *(int*)&f); /* prints all digits correctly */ 
    return 0; 
} 
$ gcc -Wall -O3 t.c 
t.c: In function ‘main’: 
t.c:7:5: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] 
$ ./a.out 
2318926848 
1326069764 

मैं अपने "चाल" है कि बिट प्रतिनिधित्व पर निर्भर करता है के साथ परिशुद्धता में वृद्धि नहीं दिख रहा है अपने मंच पर तैरता है (जहां तक ​​मैं इसे समझता हूं)।

This thread इनमें से कुछ "जादू फ्लोट" और उन्हें उत्पन्न करने का एक तरीका है।

+0

यह आईईईई 754 प्रति फ्लोट्स के थोड़ा प्रतिनिधित्व पर निर्भर करता है, न कि "आपके प्लेटफ़ॉर्म पर"। (मॉड्यूलो संभव बाइट ऑर्डर मुद्दे जो किसी वास्तविक दुनिया की मशीनों पर मौजूद नहीं हैं।) आईएमओ इस तरह के कोड के बारे में एकमात्र चीज है जो अनुचित प्रकार-पनिंग है जिसे यूनियनों के साथ प्रतिस्थापित किया जाना चाहिए (स्केची लेकिन जानबूझकर सभी कंपाइलर्स द्वारा समर्थित) या 'memcpy' (100% कानूनी सी)। –

+0

यदि आईईईई 754 अनिवार्य है, तो '__STDC_IEC_559__' परिभाषित करने के लिए क्या उपयोग है? – Mat

+0

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

0

परिशुद्धता की सीमा फ्लोटिंग पॉइंट प्रस्तुति के साथ है, printf() के साथ यह एक झूठा आधार नहीं है।

इसके अलावा एक एकल परिशुद्धता फ्लोट केवल परिशुद्धता के 6 अंकों के लिए सही गारंटी है, इसलिए "चाल" स्वयं को बेवकूफ बना देगी; सामान्य मामले में यह काम नहीं करेगा।

आप 10 अंकों चल बिन्दु संख्या तो आप डबल परिशुद्धता, जो 15 अंक के लिए अच्छा है का उपयोग करना चाहिए चाहते हैं।