फ्लोट से बाइट सरणी लंबाई 4 (char * की सरणी) को कैसे परिवर्तित करें? मुझे नेटवर्क पर कुछ डेटा भेजने की जरूरत है, टीसीपी, और एक बाइट सरणी के रूप में फ्लोट भेजने की जरूरत है। (मुझे दो दशमलव अंकों की सटीकता पता है, इसलिए फिलहाल मैं क्लाइंट साइड 100 से गुणा करता हूं और 100 से सर्वर पर विभाजित होता है - मूल रूप से पूर्णांक में परिवर्तित होता है और फिर & 0xff < < संचालन के साथ बाइट्स ढूंढें)। लेकिन यह बदसूरत है और समय के दौरान परिशुद्धता खो सकता है।फ्लोट से बाइट सरणी लंबाई 4 (char * की सरणी) को कैसे परिवर्तित करें?
उत्तर
बाइट्स की एक दृश्य के रूप में किसी भी प्रकार पढ़ना काफी सरल है:
float f = 0.5f;
unsigned char const * p = reinterpret_cast<unsigned char const *>(&f);
for (std::size_t i = 0; i != sizeof(float); ++i)
{
std::printf("The byte #%zu is 0x%02X\n", i, p[i]);
}
एक नेटवर्क धारा से एक नाव के लिए लेखन इसी तरह काम करता है, केवल आप const
बाहर छोड़ चाहते हैं।
यह हमेशा (किसी भी char
प्रकार की अनुमति है) बाइट्स की एक दृश्य के रूप में किसी भी वस्तु पुनर्व्याख्या करने की अनुमति दी है, और यह स्पष्ट रूप से नहीं एक अलियासिंग उल्लंघन कर रहा है। ध्यान दें कि किसी भी प्रकार का द्विआधारी प्रतिनिधित्व निश्चित रूप से प्लेटफॉर्म पर निर्भर है, इसलिए यदि आप प्राप्तकर्ता के पास एक ही मंच है तो आपको केवल क्रमिकरण के लिए इसका उपयोग करना चाहिए।
लेकिन, ज़ाहिर है, अगर वह नेटवर्क पर बाइट लिखना है तो यह वास्तव में उसकी मदद नहीं करता है। –
@JamesKanze: 'लिखने (FD, पी, sizeof (नाव))' ... बेशक, आप उपयोग कर सकते हैं सवाल जो कर सकते हैं * पढ़ा * कि :-) –
वहाँ व्यावहारिक रूप से किसी भी हालत जहां 'write' सही होगा है। लेकिन सवाल नेटवर्क पर उत्पादन करना था। तो वह जो लिखता है वह प्रारूप के अनुरूप होना चाहिए जो प्रोटोकॉल का उपयोग कर रहा है। –
नेटवर्क प्रोटोकॉल में फ्लोट के प्रारूप को निर्धारित करने के लिए आपको सबसे पहले करना है। सिर्फ यह जानकर कि यह 4 बाइट्स आपको बहुत कुछ नहीं बताता है: आईबीएम मेनफ्रेम, ओरेकल स्पार्क और सामान्य पीसी में चार बाइट फ्लोट हैं, लेकिन उनके पास तीन अलग प्रारूप हैं। एक बार जब आप प्रारूप पता है, यह और अपने पोर्टेबिलिटी आवश्यकताओं के आधार पर, दो अलग अलग रणनीतियों इस्तेमाल किया जा सकता:
तो प्रोटोकॉल में प्रारूप आईईईई (सबसे अक्सर मामले), है और आप हो की जरूरत नहीं है मशीनों के लिए पोर्टेबल जो आईईईई नहीं कर रहे हैं (Windows और अधिकांश यूनिक्स आईईईई रहे हैं — सबसे mainframes नहीं), तो आप प्रकार punning उपयोग कर सकते हैं कि, का उपयोग कर एक uint32_t
को नाव, और उत्पादन कन्वर्ट करने के लिए या तो:
std::ostream&
output32BitUInt(std::ostream& dest, uint32_t value)
{
dest.put((value >> 24) & 0xFF);
dest.put((value >> 16) & 0xFF);
dest.put((value >> 8) & 0xFF);
dest.put((value ) & 0xFF);
}
बड़े-एंडियन (सामान्य नेटवर्क ऑर्डर) के लिए, या:
std::ostream&
output32BitUInt(std::ostream& dest, uint32_t value)
{
dest.put((value ) & 0xFF);
dest.put((value >> 8) & 0xFF);
dest.put((value >> 16) & 0xFF);
dest.put((value >> 24) & 0xFF);
}
छोटे-अंत (कुछ प्रोटोकॉल द्वारा उपयोग किया जाता है) के लिए। आप का उपयोग करने वाले प्रोटोकॉल के लिए परिभाषित प्रारूप पर निर्भर करेंगे।
float
से uint32_t
में कनवर्ट करने के लिए, आपको अपना कंपाइलर देखना होगा। memcpy
का उपयोग करने का एकमात्र तरीका मानक द्वारा पूरी तरह से गारंटीकृत है; इरादा यह है कि फ्लोट काम पर reinterpret_cast<uint32_t&>
का उपयोग करके, और अधिकांश (सभी?) कंपाइलर union
का उपयोग करके भी समर्थन करते हैं।
आप के रूप में अच्छी mainframes करने के लिए पोर्टेबल होने की जरूरत है, या प्रारूप आईईईई के अलावा कुछ है, तो आप लक्ष्य प्रारूप में, प्रतिपादक निकालने नाव से साइन इन करें और अपूर्णांश, और उत्पादन प्रत्येक की आवश्यकता होगी ।निम्नलिखित की तरह कुछ पर उत्पादन आईईईई बड़े endian करने के लिए काम करना चाहिए (mainframes जो आईईईई का उपयोग नहीं करते सहित) किसी भी मशीन, और आप कुछ पता चलना चाहिए:
oxdrstream&
oxdrstream::operator<<(
float source)
{
BytePutter dest(*this) ;
bool isNeg = source < 0 ;
if (isNeg) {
source = - source ;
}
int exp ;
if (source == 0.0) {
exp = 0 ;
} else {
source = ldexp(frexp(source, &exp), 24) ;
exp += 126 ;
}
uint32_t mant = source ;
dest.put((isNeg ? 0x80 : 0x00) | exp >> 1) ;
dest.put(((exp << 7) & 0x80) | ((mant >> 16) & 0x7F)) ;
dest.put(mant >> 8) ;
dest.put(mant ) ;
return *this ;
}
(BytePutter
एक साधारण वर्ग है जो सामान्य बॉयलरप्लेट का ख्याल रखता है और बेशक त्रुटि जाँच करता है।), उत्पादन के लिए विभिन्न जोड़तोड़ अगर उत्पादन प्रारूप आईईईई नहीं है अलग होगा, लेकिन इस बुनियादी सिद्धांतों को दिखाना चाहिए। (आप अधिक विदेशी mainframes, जो uint32_t
का समर्थन नहीं करते में से कुछ के पोर्टेबिलिटी की जरूरत है, आप किसी भी अहस्ताक्षरित अभिन्न प्रकार है जो बड़ा की तुलना में 23 बिट है के साथ बदल सकते हैं।)
बस एक में डेटा ओवरले क्षेत्र, सी
union dataUnion {
float f;
char fBuff[sizeof(float)];
}
// to use:
dataUnion myUnion;
//
myUnion.f = 3.24;
for(int i=0;i<sizeof(float);i++)
fputc(myUnion.fbuff[i],fp); // or what ever stream output....
- 1. पार्सिंग बाइट सरणी अज्ञात लंबाई
- 2. बाइट [] से char []
- 3. आईएसओ में NSData से बाइट सरणी को कैसे परिवर्तित करें?
- 4. बाइट सरणी से ब्लॉब को कैसे परिवर्तित करें
- 5. मैं सी में "char *" सरणी की लंबाई कैसे प्राप्त करूं?
- 6. सी ++ सीएलआर में सरणी <System :: Byte> char char * को कैसे परिवर्तित करें?
- 7. बाइट सरणी से NSString
- 8. एंड्रॉइड: बाइट सरणी को बिटमैप में कैसे परिवर्तित करें?
- 9. बाइट सरणी को छवि फ़ाइल में कैसे परिवर्तित करें?
- 10. जावा में बाइट सरणी में छवि को कैसे परिवर्तित करें?
- 11. बाइट सरणी
- 12. बाइट सरणी
- 13. सरणी की लंबाई
- 14. बाइट [] से इनपुटस्ट्रीम को कैसे परिवर्तित करें?
- 15. पायथन: स्ट्रिंग को बाइट सरणी में परिवर्तित करें
- 16. बाइट सरणी
- 17. बाइट सरणी से लाइन पढ़ें (बाइट सरणी को स्ट्रिंग में कनवर्ट नहीं करें)
- 18. इस बाइट सरणी को 1024
- 19. सिमड सरणी मनमानी सरणी लंबाई
- 20. जावा बाइट [] सरणी की तुलना कैसे करें?
- 21. शाब्दिक सरणी की लंबाई कैसे प्राप्त करें?
- 22. स्ट्रिंग सरणी की लंबाई कैसे प्राप्त करें?
- 23. बाइट की अधिकतम लंबाई []?
- 24. मैं जावा बाइट सरणी को स्कैला बाइट सरणी में कैसे परिवर्तित करूं?
- 25. बाइट सरणी से CGImage
- 26. बिटमैप को बाइट सरणी में कनवर्ट करें
- 27. आईफोन में बेस 64 स्ट्रिंग से बाइट्स की सरणी को कैसे परिवर्तित करें?
- 28. PHP: अपने मानों की लंबाई से सरणी को सॉर्ट करें?
- 29. जावा: बाइट सरणी को "ट्रिम" कैसे करें?
- 30. कैसे बाइट सरणी
मुझे लगता है कि आपको सटीकता रखने के लिए 8 बाइट की आवश्यकता है। –
@ हेनो ब्रांड्समा सामान्य रूप से यह 'डबल' है। अधिकांश आधुनिक प्रणालियों पर, 'फ्लोट' 4-बाइट आईईईई -754 प्रारूप है। –
अपने अंतिम समाधान में एंडियन एकाउंटिंग को छूट न दें जबतक कि आप अपने क्लाइंट/सर्वर को एक प्रारूप (बड़े या छोटे) पर सीमित नहीं कर रहे हैं। – WhozCraig