2011-03-24 15 views
7

在C我会这样做获取C#中整数的高低字节,并将其作为char数组发送到com端口,怎么样?

int number = 3510;

char upper = number >> 8;

char lower = number & & 8;

SendByte(upper);

SendByte(lower);

在哪里上下既能= 54

在C#我这样做:

  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 upper = 54这是非常奇怪的。

基本上我只是想从16位数字上下字节,而“GETDM”

我怎样才能做到这一点后发送出去的COM端口?它在C中非常简单,但在C#中我完全难倒了。

回答

27

你的屏蔽是不正确的 - 你应该屏蔽255(0xff)而不是8屏蔽。按照“位移”的方式移动工作,而按位和/或针对屏蔽的值工作...所以如果你只需要保留底部的8位,你需要一个只有最低8位设置的掩码 - 例如255。

请注意,如果你想将一个数字分成两个字节,它应该是一个真正的不是int(它有四个字节)。

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

请注意,我用ushort这里,而不是作为byte按位算术更容易想想,当你不需要担心符号扩展。在这种情况下,由于缩小转换为byte的工作方式并不重要,但这是您应该考虑的事情。

+0

哦哇我是一个延迟,显然面具与0xff是我想要的,不知道为什么我写了8,猜测我在想8位。 – rolls 2011-03-24 13:44:19

+2

'byte lower =(byte)number;'应该这样做 – 2013-07-17 13:31:36

+0

@NikitaBrizhak:是的,但我觉得上面的方法比较简单:) – 2013-07-17 13:34:35

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

请注意,这不是endian-clean。 – 2013-12-11 05:40:18

2

即使接受的答案符合这个问题,我认为它是不完整的,因为这个问题包含int和不在头中的短小,它在搜索结果中有误导性,并且正如我们所知,C#中的Int32具有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. FF FF 03 00
  3. 7C 92
  4. FF。

如果它是很难理解我创建的方法,那么下面可能是一个更易于理解的一个:

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. 而不是转换为十六进制字符串和创建小端字符串,你可以转换为字符,并做任何你想要的东西O操作。

希望这会帮助别人!

相关问题