2012-01-07 14 views
12

के साथ "एक अंक एक्सपोनेंट" कैसे प्राप्त करें, संख्या के एक्सपोनेंट भाग के लिए 3 से कम स्थानों पर वैज्ञानिक नोटेशन में प्रिंट करने का कोई तरीका है? 6.1 स्वरूपण प्रतिपादक लेकिन केवल संख्या भाग को प्रभावित नहीं करता:सी ++ प्रिंटफ

var=1.23e-9; 
printf ("%e\n", var); 
printf ("%6.1e\n", var); 

1.230000e-009 
1.2e-009 

मैं भी स्ट्रिंग के स्वरूपण के साथ wxWidgets में यह कोशिश की है देता है, लेकिन व्यवहार में ही है।

m_var->SetLabel(wxString::Format(wxT("%6.1e"),var)); 

मैं क्या चाहता हूं 1.2e-9 है।

+7

असल में, मानक और जी ++ के अनुसार, इसका परिणाम एक्सपोनेंट भाग के लिए * दो * अंक होना चाहिए। –

उत्तर

6

मुझे यह बहुत कुछ करना पड़ा (मैं फ़ाइल पार्सर लिखता हूं और एनआईटीएफ जैसे कुछ फ़ाइल स्वरूपों को आपको संख्यात्मक मानों को स्ट्रिंग के रूप में स्टोर करने की आवश्यकता होती है)।

आप जो करते हैं वह आधार -10 गणित (वैज्ञानिक नोटेशन) का अर्थ वास्तव में क्या है इसका एक शोषण है: इसका मतलब है कि सभी वास्तविक संख्या वाई, वाई = (x) * 10^(एन) कुछ पूर्णांक एन और कुछ के लिए सीमा में एक्स (-1, 1) अनन्य।

तो, आप निम्नलिखित

void PrintScientific(double d) 
{ 
    int exponent = (int)floor(log10(fabs(d))); // This will round down the exponent 
    double base = d * pow(10, -1.0*exponent); 

    printf("%lfE%+01d", base, exponent); 
} 

आप के बाद सभी प्रारूप विनिर्देशक तुम से पहले वर्ण का # नियंत्रित करने के लिए की जरूरत है, जोड़ सकते हैं करते हैं "।" दशमलव स्थान।

राउंडिंग चरण को न भूलें!बेस 10 और लॉगरिदम (यहां बेस 10) के गुणों का उपयोग करके यह काम करता है:

वाई = x * 10^एन =>
लॉग (वाई) = लॉग (x * 10^एन) =>
लॉग (y) = लॉग (x) + लॉग (10^एन) => // प्रवेश करें "उत्पाद" नियम
लॉग (y) = लॉग से (x) + एन

के बाद से एक्स में है रेंज (-10, 10) - "()" का अर्थ अनन्य (अनन्य) है, जिसका अर्थ है कि लॉग (x) सीमा में है (-1, 1)। तो जब हम पूर्णांक रूपांतरण के लिए गोल करते हैं, तो हम "लॉग (x)" योगदान छोड़ रहे हैं। फिर आप मूल संख्या से "x" भाग प्राप्त कर सकते हैं, जिससे आप किसी भी वैज्ञानिक नोटेशन में मूल को आउटपुट कर सकते हैं जिसका आप उपयोग करना चाहते हैं।

+0

गणित 10 और उप-सामान्य संख्याओं की शक्तियों के पास कोने के मामलों में असंगत परिणामों के साथ बनाने के साथ और 0 डी, 0, आईएनएफ, एनएएन के साथ एक समस्या है। यह 'आधार' में त्रुटियों को भी पेश करेगा। – chux

12

Wikipedia के अनुसार:

प्रतिपादक हमेशा कम से कम दो अंक होता है; यदि मान शून्य है, तो एक्सपोनेंट 00 है। विंडोज़ में, एक्सपोनेंट में डिफ़ॉल्ट रूप से तीन अंक होते हैं, उदा। 1.5e002, लेकिन इसे माइक्रोसॉफ़्ट-विशिष्ट _set_output_format फ़ंक्शन द्वारा बदला जा सकता है।

_set_output_format

4
मानक सी printf() इस के साथ

नहीं किया जा सकता है (और डिफ़ॉल्ट रूप से तीन अंकों के उपयोग गलत रूप में अच्छी तरह लगता है), कम से कम C99 में (मैं पर एक नए संस्करण की जरूरत नहीं है हाथ)। C99 मानक से प्रासंगिक बोली, 7.19.6.1 पैरा 8 में है स्वरूपों ई, एफ:

.... प्रतिपादक हमेशा कम से कम दो अंक, और केवल के रूप में कई और अधिक अंक हैं आवश्यक के रूप में प्रतिनिधित्व करने के लिए प्रतिपादक। यदि मान शून्य है, तो एक्सपोनेंट शून्य है। ...

सबसे अच्छा शर्त यह [portably] कोड में इन outputs के बहुत सारे उपयोग कर रहा है सी ++ IOStreams उपयोग करने के लिए फिट करने के लिए: हालांकि डिफ़ॉल्ट स्वरूपण सी में के रूप में ही है, यह एक कस्टम पहलू स्थापित करने के लिए संभव है स्ट्रीम के std::locale में जो आपको जिस तरीके से स्वरूपण करता है उसे स्वरूपित करता है। उस ने कहा, स्वरूपण कोड लिखना पूरी तरह से तुच्छ नहीं हो सकता है। हालांकि मैं शायद मानक रूपांतरण पर बनाया गया था और फिर e चरित्र के बाद अतिरिक्त शून्य को हटा दूंगा।

1

मुझे जैच का जवाब सबसे तेज़ और सरल तरीका माना गया है और यह किसी भी ओएस पर भी लागू होता है। मुझे पता चला कि सभी संख्याओं के लिए काम करने के लिए "आधार =" रेखा पर दो संशोधन की आवश्यकता थी। (अन्यथा नैन जब एक्सपोनेंट साइगविन में नकारात्मक होता है)। अतिरिक्त प्रिंट स्टेटमेंट सिर्फ पैट्रान तटस्थ फ़ाइल संगतता के लिए है। मैंने उसका जवाब उतार दिया होगा, लेकिन मैंने अभी स्टैक्सएक्सचेंज पर शुरुआत की है, इसलिए मेरे पास पर्याप्त "प्रतिष्ठा" नहीं है।

void PrintScientific(double d) 
{ 
    int exponent = (int)floor(log10(fabs(d))); // This will round down the exponent 
    double base  = (d * pow(10.0, -1*exponent)); 

if(abs(exponent)<10) 
    printf("%13.9lfE%+01d", base, exponent); 
else 
    printf("%12.9lfE%+01d", base, exponent); 
} 
0

सी/सी ++ printf("%e",...) के साथ कम से कम दो एक्सपोनेंट अंक निर्दिष्ट करता है। केवल 1 मुद्रित करने के लिए, और विजुअल स्टूडियो से निपटने के लिए, डिफ़ॉल्ट रूप से, कम से कम 3 प्रिंट करता है, अतिरिक्त कोड की आवश्यकता होती है।

पर विचार करें IOStreams @Dietmar Kühl

सी ++ कोड अभी भी printf() शैली स्वरूपों का उपयोग करना चाहता है: कॉल करने से पहले

एक double का मूल्य समायोजन printf() भी अक्सर गोलाई मुद्दों, सीमा लघुकरण और जैसे सामान्य कोने मामले विफलताओं में परिणाम log10(0.0) से निपटना। double पर केवल log10() के पास बड़े -0.0, , INF, NAN के साथ बड़े double पर विचार करें।

इस मामले में, स्ट्रिंग को पोस्ट-प्रोसेस करने के लिए बेहतर है।

double var = 1.23e-9; 
    //     - 1 . x e - EEEEE \0 
    #define ExpectedSize (1+1+1+1+1+1+ 5 + 1) 
    char buf[ExpectedSize + 10]; 
    snprintf(buf, sizeof buf, "%.1e", var); 
    char *e = strchr(buf, 'e'); // lucky 'e' not in "Infinity" nor "NaN" 
    if (e) { 
    e++; 
    int expo = atoi(e); 
    snprintf(e, sizeof buf - (e - buf), "%1d", expo); 
    } 
    printf("'%6s'\n", buf); // '1.2e-9' 

नोट: के रूप में इसकी चौड़ाई इतनी "%f" के रूप में बोझल नहीं है %e पोस्ट-प्रोसेसिंग के लिए मिलनसार है। sprintf(buf, "%f", DBL_MAX)char के 1000s में हो सकता है।

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