2012-05-25 13 views
24

के साथ सी ++ में डबल से चार * कनवर्ट करना मेरे एप्लिकेशन को केवल एक अक्षर को स्वीकार करने वाली पाइप को लिखने के लिए डबल मान को चार * में परिवर्तित करने की आवश्यकता है। ऐसा करने का सामान्य तरीकों sprintf() समारोह का उपयोग कर या iomanip.h हेडर फाइल से ostringstream उपयोग कर रहे हैं।उच्च प्रदर्शन

बाहर निकलता है, इनमें से दोनों वास्तव में खराब प्रदर्शन करते हैं। और मेरे आवेदन को इस रूपांतरण को इतनी बार करने की ज़रूरत है कि यह प्राथमिक बाधा बन जाए।

क्या कोई अन्य कार्य है जिसका मैं उपयोग कर सकता हूं? एक कुशल रूपांतरण समारोह लिखने के लिए मैं किस तर्क का उपयोग कर सकता हूं? एकमात्र चीज जिसे मैंने अभी तक पूरा करने में कामयाब रहा है वह है कि प्रत्येक व्यक्तिगत अंक को डिवीजन और मॉड ऑपरेशंस का उपयोग करके बाहर निकालना है, और इन अंकों को पूरे डबल मान प्राप्त करने के लिए char * में जोड़ना है। हालांकि यह एक अच्छा दृष्टिकोण की तरह प्रतीत नहीं होता है, और संभवतः खराब प्रदर्शन होगा।

आपके विचारों के लिए अग्रिम धन्यवाद।

संपादित करें: वहाँ कैसे चार * उपयोग किया जाएगा पर कुछ भ्रम की स्थिति है। Char * fwrite फ़ंक्शन के लिए एक तर्क होगा जो एक पाइप को लिखता है।

+4

"पाइप केवल वर्णों को स्वीकार करता है" से आपका क्या मतलब है? क्या आप बाइट्स भेज/लिख सकते हैं? क्या प्रारूप जिसमें डेटा इस पाइप मामले में जाता है (क्या इसे मानव पठनीय होने की आवश्यकता है), या आप इसे दूसरी तरफ वापस परिवर्तित करते हैं? – dbrank0

+2

इसे पढ़ें: http://stackoverflow.com/questions/3173056/why-does-dtoa-c-contain-so-much-code – nhahtdh

+0

क्यों एक int को बिटकास्ट नहीं है और हेक्स में एन्कोड करें और उसे भेजें (फिर उस पर दूसरी तरफ वापस कनवर्ट करें) –

उत्तर

17

आप किसी भी संख्या है कि डबल प्रकार का समर्थन कर सकते हैं, उपयोग जो कुछ भी वहाँ बाहर पुस्तकालय काम करने के लिए प्रिंट करना चाहते हैं। आप डबल प्रकार में संख्या का एक सबसेट प्रिंट करना चाहते हैं Why does "dtoa.c" contain so much code?

: यह आपके विवेक बचत होती है। उदाहरण के लिए, दशमलव बिंदु के बाद 4 अंकों तक, और दशमलव बिंदु से पहले 5 अंकों से अधिक नहीं, तो आप विभाजन और मोड का उपयोग करके इसे प्रिंट करने से पहले संख्या को गोल कर सकते हैं और int प्रकार में परिवर्तित कर सकते हैं। मैं इस विधि के प्रदर्शन की पुष्टि कर सकता हूं।


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

+0

+1: यदि ओपी वर्तमान में फ्लोट की सीमा के बारे में कुछ जानता है, तो स्केल किए गए पूर्णांक रूपांतरण शायद सबसे अच्छा अनुकूलन है। – wallyk

+6

वह डबल की सामग्री को क्रमबद्ध करना चाहता है। इसका प्रतिनिधित्व करने की कोई आवश्यकता नहीं है। – RedX

7

यदि आप बाइट द्वारा डेटा बाइट पढ़ना चाहते हैं। इस तकनीक का उपयोग करें

double dbl = 2222; 
char* ptr = (char*)(&dbl); 

यह डीबीएल के निम्नतम बाइट को वापस कर देगा। और पीआरटी ++ डीबीएल के दूसरे बाइट को संदर्भित करेगा।

+1

यह टाइप कास्टिंग नहीं है। प्रश्न डबल के मुद्रण मूल्य के बारे में है। – nhahtdh

+1

उसे इसे वर्णों से भेजने की ज़रूरत है, और मुझे लगता है कि यह इसके द्वारा किया जा सकता है क्योंकि आपके पास डबल वैरिएबल के बाइट हैं और जब सभी बाइट दूसरे छोर पर प्राप्त होते हैं तो – Saad

+0

पर आप सही हो सकते हैं। प्रश्न रूपांतरण के उद्देश्य के बारे में स्पष्ट नहीं है। – nhahtdh

2

कुछ प्रणालियों dtostre और dtostrf रूपांतरण कार्यों प्रदान करते हैं - बेंचमार्किंग लायक हो सकता है। आप विचारों के लिए sprintf() स्रोत कोड (उदाहरण के लिए जीएनयू संस्करण) देख सकते हैं, %e, %f और/या %g वांछित स्वरूपण को स्वरूपित करना, प्रारूप स्ट्रिंग व्याख्या चरण से बचने और यहां तक ​​कि इसे अपरिवर्तनीय बनाने और स्वाद के लिए प्रदर्शन-ट्यून को भी देख सकते हैं - आप शायद यदि आप जानते हैं कि आपको उन्हें संभालना नहीं है तो NaN, अनंतता और अन्य मानों के लिए विशेष आवरण को हटाने में सक्षम हो।

1

ftoa का उपयोग sprintf की तुलना में थोड़ा बेहतर होगा के रूप में यह है कि क्या वह आंतरिक रूप से उपयोग कर रहा है। संबंधित प्रश्न देखें here यह भी देखें कि आपके लाइब्रेरी स्रोत में ftoa कैसे कार्यान्वित किया गया है और देखें कि क्या आप अपने विशिष्ट परिदृश्यों के लिए इसमें सुधार कर सकते हैं।

ऐसा लगता है कि ftoa मानक नहीं है, मेरे बुरे। यहां एक discussion showing an implementation है जो स्प्रिंटफ को बहुत तेज होने का दावा करता है। आपको अपने लक्ष्य वातावरण दोनों पर प्रोफाइल करना होगा, और फ्लोट के बजाए डबल के साथ कार्यान्वित करना होगा।

+0

किसी भी संस्करण में विनिर्देशन में ftoa (फ्लोट के लिए) या dtoa (डबल के लिए) है? – nhahtdh

+0

एक त्वरित जांच के बाद, स्पष्ट रूप से नहीं! मैं कुछ rummaging चारों ओर करूँगा क्योंकि मैंने निश्चित रूप से इसे देखा है जब कुछ पुस्तकालयों के माध्यम से एकल कदम। संभवतः मानक के रूप में मैंने सोचा नहीं। –

8

आप के साथ read तरीकों किसी भी डेटा टाइप तुम सिर्फ एक चार सूचक के रूप में डेटा reinterpret_cast करने के लिए है std :: ostream write और std :: IStream का उपयोग कर सकते हैं:

double value = 5.0; 
std::ostream os; 
//... 
os.write(reinterpret_cast<const char*>(&value), sizeof(value)); 
//.. 
std::istream is; 
is.read(reinterpret_cast<char*>(&value), sizeof(value)); 
+0

मुझे नहीं लगता कि यह तेज़ होगा: अभी भी आपके प्रयास के लिए +1 ..! –

2

पर sprintf की धीमी गति से भाग अपने सिस्टम आवश्यक रूप से डबल को परिवर्तित नहीं कर सकता है, लेकिन प्रारूप स्ट्रिंग को पार्स कर रहा है। यह आपके लिए अच्छी खबर हो सकती है क्योंकि यह ऐसा कुछ है जिसे आप दूर कर सकते हैं।

इसके अतिरिक्त, double मानों की सीमा, सटीकता और प्रकृति के बारे में आपके सभी ज्ञान को दस्तावेज करने के लिए कड़ी मेहनत करें, जिन्हें आप संसाधित करने की आवश्यकता है, और एक विशेष एल्गोरिदम विकसित करने के लिए इसका उपयोग करें।

मान लिया जाये कि आपके इनपुट, सामान्य से कम संख्या कभी नहीं कर रहे हैं एक ज्ञात तय परिशुद्धता और सटीकता का उपयोग करें, एक अपेक्षाकृत अच्छा प्रदर्शन करने वाले परिणाम कुछ ऐसा दिखाई देगा:

itoa((int)((f + 0.00001) * 10000)) 

हालांकि, sprintf और ostream दृष्टिकोण आप पहले से ही कर रहे हैं के बारे में पता कर रहे हैं एकमात्र समाधान जो पूरी तरह से सामान्य और पोर्टेबल हैं।

+1

दशमलव बिंदु मुद्रित नहीं किया जाएगा। – nhahtdh

+0

@nhahtdh - यह सच है।मैं अपने उत्तर को पूरी तरह से हटा दूंगा जब तक कि मुझे प्रश्न संपादन दिखाई नहीं देते जो आउटपुट पाइप के सटीक उद्देश्य को स्पष्ट करेंगे। अंत में बाइनरी में तैरते हुए एक उत्कृष्ट समाधान (केसी का जवाब) हो सकता है, या यह अनुपयोगी हो सकता है। –

+0

हालांकि सीधे लागू नहीं है, आपका उत्तर मुझे समस्या को हल करने के तरीके पर कुछ लीड देता है। धन्यवाद! –

2
/* 

_ecvt_s Converts a double number to a string. 

Syntax: 

errno_t _ecvt_s( 
    char * _Buffer, 
    size_t _SizeInBytes, 
    double _Value, 
    int _Count, 
    int *_Dec, 
    int *_Sign 
); 

[out] _Buffer 
Filled with the pointer to the string of digits, the result of the conversion. 

[in] _SizeInBytes 
Size of the buffer in bytes. 

[in] _Value 
Number to be converted. 

[in] _Count 
Number of digits stored. 

[out] _Dec 
Stored decimal-point position. 

[out] _Sign 
Sign of the converted number. 


*/ 


#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 

... 
char *buf = (char*) malloc(_CVTBUFSIZE); 
int decimal; 
int sign; 
int err; 


err = _ecvt_s(buf, _CVTBUFSIZE, 1.2, 5, &decimal, &sign); 

if (err != 0) { 
// implement error handling 
} 
else printf("Converted value: %s\n", buf); 

... 

उम्मीद है कि इससे मदद मिलती है।

3

क्या आप पाइप के दोनों सिरों के नियंत्रण में हैं? क्या आप सिर्फ युगल के माध्यम से सुरंग करने की कोशिश कर रहे हैं या आपको डबल के वैध पाठ प्रतिनिधित्व की आवश्यकता है?

यदि आप केवल सुरंग कर रहे हैं और पाइप 8 बिट साफ है तो ऊपर दिए गए उत्तरों में से एक का उपयोग करें।

यदि आपको उपरोक्त अन्य उत्तरों में से एक स्ट्रिंग का उपयोग करने की आवश्यकता है।

यदि आपकी समस्या यह है कि पाइप केवल 7 बिट चौड़ा है, तो radix 64 पर लिखें और फिर पढ़ने पर वापस बदलें।

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