2009-05-05 21 views
6

एक हस्ताक्षरित चार सरणी को C++ में फ़्लोट सरणी में परिवर्तित करने का सबसे अच्छा तरीका क्या है?फ़्लोट्स की एक सरणी में हस्ताक्षरित वर्णों की एक सरणी कास्टिंग

मैं इस समय के रूप में

for (i=0 ;i< len; i++) 
    float_buff[i]= (float) char_buff[i]; 

इस प्रकार पाश के लिए एक है मैं भी (8 बिट रूपांतरण के लिए नाव)

for (i=0 ;i< len; i++) 
    char_buff[i]= (unsigned char) float_buff[i]; 

किसी भी होगा सलाह फ्लोट करने के लिए प्रक्रिया को उल्टा, यानी अहस्ताक्षरित चार से बदलने की आवश्यकता

धन्यवाद

+1

आप क्या कर रहे हैं जिसके लिए इसकी आवश्यकता है? –

उत्तर

2

आपका समाधान लगता है ठीक है, हालांकि वापस रास्ते पर, आप कास्टिंग में फ़्लोटिंग अंक खो सकते हैं।

+0

धन्यवाद मैं उलझन में हूं कि किस सी ++ शैली का उपयोग करने के लिए कास्ट किया गया है (पुन: व्याख्या या स्थैतिक), इसलिए मैंने पुरानी शैली, किसी भी विचार का उपयोग किया। इसके अलावा, फ्लोट से 25/10.0 से अधिक होने पर फ्लोट से अप्रमाणित चार में कनवर्ट करते समय क्या होता है। (बिंदु के बाद अंकों के बारे में चिंतित नहीं) धन्यवाद –

+0

यदि फ्लोट 255 से बड़ा है, तो इसमें कास्ट के बाद एमओडी परिणाम होगा (किसी अन्य ओवरफ्लो के साथ)। उदाहरण के लिए: फ्लोट = 500 -> char = 254. float = 256 -> char = 0. बीटीडब्लू, यहां static_cast पर कुछ जानकारी दी गई है: http://stackoverflow.com/questions/103512/in-c-why-use-staticcastintx -instead-of-intx –

+0

व्यवहार अगर फ्लोट है> = 256 अपरिभाषित है - एक मॉड्यूलो मान प्राप्त करना आम हो सकता है, लेकिन इसकी गारंटी नहीं है। –

2

आप इस उद्देश्य के लिए क्या कर रहे हैं? एक चार में एक फ्लोट को झुकाव वास्तव में समझ में नहीं आता है। अधिकांश प्लेटफ़ॉर्म पर एक फ्लोट 4 बाइट्स होगा और एक फ़्लोटिंग पॉइंट नंबर का प्रतिनिधित्व करेगा, जहां एक char 1 बाइट होगा और अक्सर एक वर्ण का प्रतिनिधित्व करता है। आप डेटा में 3 बाइट खो देंगे, एक फ्लोट को एक चार में घुमाने की कोशिश कर रहे हैं, है ना?

+0

धन्यवाद मुझे फ्लोट से 8 बिट –

+0

में कनवर्ट करने की आवश्यकता है, कलाकार एक रूपांतरण करेगा - फ्लोट के आंशिक भाग को छोटा कर देगा। यह वही हो सकता है जो व्यक्ति चाहता है। इसके बारे में जागरूक होने की एक महत्वपूर्ण बात यह है कि अगर फ्लोट का अभिन्न हिस्सा किसी हस्ताक्षरित चार में प्रदर्शित नहीं किया जा सकता है (आमतौर पर यदि यह 0-255 की सीमा में नहीं है) तो यह अनिर्धारित है। –

+0

धन्यवाद माइकल, मुझे आंशिक भाग खोने में कोई फर्क नहीं पड़ता। यदि फ्लोट 255 से कम है, तो क्या कास्ट ठीक काम करेगा? अगर फ्लोट इस से बड़ा था तो मैं परिणाम को 255 पर क्लैंप करने जा रहा था। धन्यवाद –

8

आपका समाधान काफी सबसे अच्छा विकल्प है, हालांकि, मैं करने के लिए बदलने पर विचार होगा:

char_buff[i]= static_cast<unsigned char>(float_buff[i]); 
0

आप बहुत बड़ी सरणियों और प्रदर्शन के लिए आवश्यक है के साथ काम कर रहे हैं तो निम्नलिखित थोड़ा और अधिक कुशल साबित हो सकता है:

float *dst = float_buff; 
    unsigned char *src = char_buff; 

    for (i=0; i<len; i++) *dst++ = (float)*src++; 
+0

धन्यवाद दान, टिप –

+0

या std :: copy (char_buff, char_buff + len, float_buff) की सराहना करते हैं; –

+0

यहां std :: प्रतिलिपि का उपयोग एसटीएल (साथ ही सी ++) में एक दोष का खुलासा करता है। जब आप किसी चीज की एक प्रति बनाते हैं, तो यह सच होना चाहिए कि कॉपी == मूल। निहित कास्टिंग पर भरोसा करके, यह अब सत्य नहीं है, यही कारण है कि निहित कास्टिंग से बचा जाना चाहिए। –

2

आपके पहले लूप को कास्ट की आवश्यकता नहीं है। आप एक प्रकार से (उदाहरण के लिए, unsigned char) को व्यापक रूप से परिवर्तित कर सकते हैं (उदाहरण के लिए, float)। आपकी दूसरी पाश static_cast उपयोग करना चाहिए:

for (i=0; i< len; i++) 
    char_buff[i]= static_cast<unsigned char>(float_buff[i]); 

हम static_cast का उपयोग स्पष्ट रूप से एक संकरा प्रकार के रूपांतरण करने के लिए संकलक बताने के लिए। यदि आप कास्ट का उपयोग नहीं करते हैं, तो आपका कंपाइलर आपको चेतावनी दे सकता है कि रूपांतरण डेटा खो सकता है। कास्ट ऑपरेटर की उपस्थिति का अर्थ है कि आप समझते हैं कि आप डेटा परिशुद्धता खो सकते हैं और आप इसके साथ ठीक हैं। यह reinterpret_cast का उपयोग करने के लिए उपयुक्त स्थान है। static_cast के साथ, आप कम से कम कुछ प्रतिबंधों पर प्रतिबंध लगा सकते हैं कि आप क्या कर सकते हैं (उदाहरण के लिए, शायद यह आपको Bird* को Nuclear_Submarine* में परिवर्तित करने नहीं देगा)। reinterpret_cast में ऐसे कोई प्रतिबंध नहीं हैं।

इसके अलावा, Bjarne Stroustrup को इस विषय के बारे में क्या कहना है।

9

मुझे लगता है कि सबसे अच्छा तरीका है एक समारोह वस्तु का उपयोग करने के लिए है:

template <typename T> // T models Any 
struct static_cast_func 
{ 
    template <typename T1> // T1 models type statically convertible to T 
    T operator()(const T1& x) const { return static_cast<T>(x); } 
}; 

द्वारा पीछा किया:

std::transform(char_buff, char_buff + len, float_buff, static_cast_func<float>()); 
std::transform(float_buff, float_buff + len, char_buff, static_cast_func<unsigned char>()); 

क्योंकि यह कहते हैं क्या अंग्रेजी में किया जा रहा है यह सबसे पढ़ी जा सकती है: एक बदलने स्थैतिक कास्टिंग का उपयोग कर एक अलग प्रकार में अनुक्रम। और भविष्य के जानवरों को एक पंक्ति में किया जा सकता है।

1

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

std::copy(char_buff,char_buff+len,float_buff); 

नाव से वापस परिवर्तित चार करने के लिए जानकारी का एक संभावित नुकसान होता है। तो आपको और अधिक स्पष्ट होना चाहिए।

std::transform(float_buff,float_buff+len,char_buff,MyTransform()); 

यहाँ हम वर्ग MyTransform जो एक ऑपरेटर होना चाहिए() है कि एक नाव ले जाता है और एक चार रिटर्न का उपयोग करें। यह प्रत्यारोपण के लिए तुच्छ होना चाहिए।

0

किसी ने इसका उल्लेख नहीं किया है, लेकिन यदि आप फ्लोट के साथ कोई अंकगणित कर रहे हैं, तो आप छंटनी के बजाय गोल करना चाहेंगे ... यदि आपके पास चार 49 है, और यह 4.9ई 1 में बदल जाता है, तो कुछ अंकगणित, यह 4.8 99 99 999 ई 1 में बदल सकता है जो 48 में बदल जाएगा जब आप इसे वापस चार में बदल देंगे।

यदि आप फ्लोट के साथ कुछ भी नहीं कर रहे हैं, तो यह कोई समस्या नहीं होनी चाहिए, लेकिन फिर आपको इसे पहले स्थान पर फ़्लोट के रूप में क्यों चाहिए?