2008-11-04 8 views
5

यदि कोई वास्तविक संख्या एक डबल के साथ बिल्कुल प्रतिनिधित्व योग्य है तो मैं एक सी ++ फ़ंक्शन को सही कैसे लौट सकता हूं?यदि कोई वास्तविक संख्या वास्तव में डबल के साथ प्रदर्शित होती है तो मैं एक सी ++ फ़ंक्शन को सही कैसे लौट सकता हूं?

bool isRepresentable(const char* realNumber) 
{ 
    bool answer = false; 
    // what goes here? 
    return answer; 
} 

सरल परीक्षण:

assert(true==isRepresentable("0.5")); 
assert(false==isRepresentable("0.1")); 

उत्तर

5

संख्या को एक + एन/(10^के) में पार्स करें, जहां ए और एन पूर्णांक हैं, और के आपके पास दशमलव स्थानों की संख्या है।

उदाहरण: 12.0345 -> 12 + 345/10^4, एक = 12, एन = 345 k = 4

अब, 10^k = (2 * 5)^कश्मीर = 2^कश्मीर * 5^के

यदि आप denominator में 5^के शब्द से छुटकारा पा रहे हैं तो आप केवल सही संख्या के बाइनरी अंश के रूप में प्रतिनिधित्व कर सकते हैं।

परिणाम की जाँच करेगा (एन आधुनिक 5^कश्मीर) == 0

+0

111111111111111111111111111111111111111111111111111111111111111 के बारे में क्या? – BCS

+0

या इसे रखने का एक बेहतर तरीका (100/ईपीएसलॉन + 1) – BCS

-2

एक डबल तुलना में एक बड़ा गुंजाइश के साथ एक नाव में स्ट्रिंग में कनवर्ट करें। इसे दो बार कास्ट करें और देखें कि वे मेल खाते हैं या नहीं।

+0

जानना चाहता है कि इस मतदान किया गया था अच्छा नहीं होगा। अगर मेरा जवाब गलत है, तो कृपया मुझे बताएं क्यों। – Treb

+0

लंबे समय से डबल == कुछ सिस्टम पर डबल – BCS

+0

सभी बहुत अच्छी तरह से, लेकिन ऐसी फ्लोट नहीं हो सकती है। – DJClayworth

0

इस चाल करना चाहिए:

bool isRepresentable(const char *realNumber) 
{ 
    double value = strtod(realNumber, NULL); 

    char test[20]; 
    sprintf(test, "%f", value); 

    return strcmp(realNumber, test) == 0; 
} 

शायद सबसे अच्छा एक संभावित बफर सीमा से अधिक को रोकने के लिए sprintf की 'सुरक्षित' संस्करण का उपयोग करने

+0

होगा यदि संख्या 6 से भिन्न परिशुद्धता है (% lf प्रारूप की डिफ़ॉल्ट परिशुद्धता) –

+0

आप गतिशील रूप से "% f" स्ट्रिंग को सेट करने के लिए सेट कर सकते हैं सही चौड़ाई आपको व्हाइटस्पेस को संभालने की आवश्यकता होगी, अग्रणी बनाम शून्य, +, -, और अन्य विशेष मामलों को पूरी तरह से मजबूत नहीं होना चाहिए। –

+0

स्नप्रिंटफ एक 'सुरक्षित' संस्करण होगा - http://publib.boulder.ibm.com/infocenter/systems/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/printf.htm –

0

मैं (यह इस मामले में भी हो सकता है?) डी स्ट्रिंग को इसके न्यूमेरिक बिट प्रस्तुति में परिवर्तित करें, (थोड़ा सरणी या एक लंबा), फिर स्ट्रिंग को एक डबल में कनवर्ट करें और देखें कि वे मेल खाते हैं या नहीं।

+0

.. और क्या होगा अगर (आपकी मशीन पर) लंबी डबल एक ही आकार के बराबर है? – DJClayworth

+0

क्षमा करें, मैंने उस टिप्पणी को गलत उत्तर पर पोस्ट किया है। – DJClayworth

1

मेरा संस्करण यहां है। sprintf 0.5 से 0.50000 परिवर्तित, अंत में शून्य हटा दिया जाना है।

संपादित करें: दशमलव बिंदु के बिना संख्याओं को संभालने के लिए फिर से लिखा जाना चाहिए जो 0 के साथ सही ढंग से समाप्त होता है (12300 की तरह)।

 
bool isRepresentable(const char* realNumber) 
{ 
    bool answer = false; 

    double dVar = atof(realNumber); 
    char check[20]; 
    sprintf(check, "%f", dVar); 

    // Remove zeros at end - TODO: Only do if decimal point in string 
    for (int i = strlen(check) - 1; i >= 0; i--) { 
    if (check[i] != '0') break; 
    check[i] = 0; 
    } 

    answer = (strcmp(realNumber, check) == 0); 

    return answer; 
} 
+0

लगभग - 1.200e10 के बारे में क्या? – DJClayworth

5

पवित्र गृहकार्य, बैटमैन! :)

यह दिलचस्प क्या है कि आप केवल एक (atof | strtod | sscanf) -> sprintf लूप नहीं कर सकते हैं और जांच सकते हैं कि आपको मूल स्ट्रिंग वापस मिल गई है या नहीं। कई प्लेटफार्मों पर स्प्रिंटफ "जितना करीब हो सके उतना करीब 0.1" प्राप्त करता है और इसे 0.1 के रूप में प्रिंट करता है, उदाहरण के लिए, हालांकि 0.1 सटीक रूप से प्रतिनिधित्व योग्य नहीं है।

#include <stdio.h> 

int main() { 
    printf("%llx = %f\n",0.1,0.1); 
} 

प्रिंट: 3fb999999999999a = 0,100000

अपने सिस्टम पर

असली उत्तर शायद इसे एक सटीक fractional प्रतिनिधित्व (0.1 = 1/10) में परिवर्तित करने के लिए डबल को पार्सिंग करने की आवश्यकता होगी और फिर यह सुनिश्चित कर लें कि उपरोक्त रूपांतरण समय पर denominator संख्यात्मक बराबर है।

मुझे लगता है।