2011-03-24 4 views
7

सी में मैं यहसी # में एक पूर्णांक के ऊपरी और निचले बाइट प्राप्त करना और कॉम पोर्ट को भेजने के लिए इसे चार सरणी के रूप में डालना, कैसे?

int संख्या = 3510;

चार ऊपरी = संख्या >> 8;

चार निचला = संख्या & & 8;

SendByte (ऊपरी);

SendByte (निचला);

कहाँ ऊपरी और निचले दोनों = 54

सी # में मैं यह कर रहा हूं:

  int number = Convert.ToInt16("3510"); 
      byte upper = byte(number >> 8); 
      byte lower = byte(number & 8); 
      char upperc = Convert.ToChar(upper); 
      char lowerc = Convert.ToChar(lower); 
      data = "GETDM" + upperc + lowerc; 
      comport.Write(data); 
डिबगर संख्या = 3510 में

हालांकि, ऊपरी = 13 और निचले = 0 यह कोई समझ नहीं आता है, अगर मैं कोड को 6 ऊपरी = 54 में बदलता हूं जो बिल्कुल अजीब है।

असल में मैं सिर्फ 16 बिट संख्या से ऊपरी और निचले बाइट मिलता है, और "GETDM"

मैं यह कैसे कर सकते के बाद इसे बाहर भेज कॉम पोर्ट करना चाहते हैं? यह सी में इतना आसान है, लेकिन सी # में मैं पूरी तरह से स्टंप हूं।

उत्तर

27

आपका मास्किंग गलत है - आपको 8 के बजाय 255 (0xff) के खिलाफ मास्किंग करना चाहिए। "बिट्स को स्थानांतरित करने" के संदर्भ में कार्यों को स्थानांतरित करना, जबकि बिटवाई और/या मास्क के लिए मास्क के लिए काम के विरुद्ध काम करना चाहिए ... तो अगर आप केवल 8 बिट्स को रखना चाहते हैं, आपको केवल एक मुखौटा की आवश्यकता है जिसमें नीचे 8 बिट सेट हैं - यानी 255.

ध्यान दें कि यदि आप किसी संख्या को दो बाइट्स में विभाजित करने का प्रयास कर रहे हैं, तो यह वास्तव में होना चाहिए int (जिसमें चार बाइट्स हैं) के साथ शुरू करने के लिए छोटा या ushort)।

ushort number = Convert.ToUInt16("3510"); 
byte upper = (byte) (number >> 8); 
byte lower = (byte) (number & 0xff); 

ध्यान दें कि मैं ushort यहाँ के बजाय byte का उपयोग किया है बिटवाइज़ गणित के रूप में सोचने के लिए आसान के बारे में जब आप हस्ताक्षर विस्तार के बारे में चिंता करने की जरूरत नहीं है। byte कामों को संकुचित करने के तरीके के कारण यह वास्तव में इस मामले में कोई फर्क नहीं पड़ता है, लेकिन यह ऐसी चीज है जिसके बारे में आपको सोचना चाहिए।

+0

ओह वाह मैं एक मंद हूं, स्पष्ट रूप से 0xff के साथ मुखौटा है जो मुझे चाहिए, मुझे नहीं पता कि मैंने 8 क्यों लिखा था, अनुमान है कि मैं 8 बिट्स सोच रहा था। – rolls

+2

'बाइट निचला = (बाइट) संख्या; ' –

+0

@NikitaBrizhak भी करना चाहिए: सच है, लेकिन मुझे इसके बारे में सोचने के लिए सरल से ऊपर का दृष्टिकोण मिलता है :) –

2

यह हो नहीं करना चाहिए:

byte lower = (byte) (number & 0xFF); 
4

आप शायद करना चाहते हैं और यह 0x00FF

byte lower = Convert.ToByte(number & 0x00FF); 

पूर्ण उदाहरण के साथ:

ushort number = Convert.ToUInt16("3510"); 
byte upper = Convert.ToByte(number >> 8); 
byte lower = Convert.ToByte(number & 0x00FF); 
char upperc = Convert.ToChar(upper); 
char lowerc = Convert.ToChar(lower); 
data = "GETDM" + upperc + lowerc; 
1

थोड़ा और अधिक रचनात्मक होना करने के लिए

[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)] 
public struct IntToBytes { 
    [System.Runtime.InteropServices.FieldOffset(0)] 
    public int Int32; 
    [System.Runtime.InteropServices.FieldOffset(0)] 
    public byte First; 
    [System.Runtime.InteropServices.FieldOffset(1)] 
    public byte Second; 
    [System.Runtime.InteropServices.FieldOffset(2)] 
    public byte Third; 
    [System.Runtime.InteropServices.FieldOffset(3)] 
    public byte Fourth; 
} 
+0

ध्यान दें कि यह एंडियन-क्लीन नहीं है। –

2

भले ही स्वीकृत उत्तर प्रश्न के अनुरूप हो, मैं इस तथ्य को सरल मानता हूं कि प्रश्न में अंतर्निहित है और शीर्षलेख में छोटा नहीं है और यह खोज परिणामों में भ्रामक है, और जैसा कि हम जानते हैं कि सी # में इंट 32 में 32 बिट्स हैं और इस प्रकार 4 बाइट्स। मैं यहां एक उदाहरण पोस्ट करूंगा जो Int32 उपयोग के मामले में उपयोगी होगा। कोई Int32 के मामले में हमने:

  1. LowWordLowByte
  2. LowWordHighByte
  3. HighWordLowByte
  4. HighWordHighByte।

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

public static String IntToLittleEndianWhitespacedHexString(int pValue, uint pSize) 
{ 
    String result = String.Empty; 

    pSize = pSize < 4 ? pSize : 4; 

    byte tmpByte = 0x00; 
    for (int i = 0; i < pSize; i++) 
    { 
     tmpByte = (byte)((pValue >> i * 8) & 0xFF); 
     result += tmpByte.ToString("X2") + " "; 
    } 

    return result.TrimEnd(' '); 
} 

उपयोग:

String value1 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x927C, 4); 
String value2 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x3FFFF, 4); 
String value3 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x927C, 2); 
String value4 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x3FFFF, 1); 

परिणाम है:

  1. 7C 92 00 00
  2. एफएफ एफएफ 03 00
  3. 7C 92
  4. एफएफ।

यदि यह विधि है जो मेरे द्वारा बनाए गए समझना कठिन है, तो निम्नलिखित एक अधिक सुबोध एक हो सकता है:

public static String IntToLittleEndianWhitespacedHexString(int pValue) 
{ 
    String result = String.Empty; 
    byte lowWordLowByte = (byte)(pValue & 0xFF); 
    byte lowWordHighByte = (byte)((pValue >> 8) & 0xFF); 
    byte highWordLowByte = (byte)((pValue >> 16) & 0xFF); 
    byte highWordHighByte = (byte)((pValue >> 24) & 0xFF); 

    result = lowWordLowByte.ToString("X2") + " " + 
      lowWordHighByte.ToString("X2") + " " + 
      highWordLowByte.ToString("X2") + " " + 
      highWordHighByte.ToString("X2"); 

    return result; 
} 

टिप्पणी:

  1. बेशक वहाँ uint pSize की insteand बाइट, वर्ड, डबलवॉर्ड
  2. हेक्स स्ट्रिंग में परिवर्तित करने और छोटी एंडियन स्ट्रिंग बनाने के बजाय, आप वर्णों में परिवर्तित कर सकते हैं और जो कुछ भी आप करना चाहते हैं उसे करने के बजाय एक enum हो सकता है ओ।

आशा है कि यह किसी की मदद करेगा!

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