将字节连接成整数或短整型并保留符号

6

我知道可以像这样从int中提取字节:

bytes[] IntToBytes(int i)
{
  return new byte [] {(byte) ((i >> 8) & 0xff), (byte) (i & 0xff)};
}

我将其作为串行传输的一部分发送。但是,我是否可以在接收到一系列字节后进行反向操作,重构原始数据并保留符号。目前,我已经这样做了,但感觉有点过头了:

int BytesToInt( byte hi, byte lo)
{
  return ((hi << 24) | (lo << 16)) >> 16;
}

还有其他或更好的方法吗?如果我知道最终只涉及有符号的16位数据,这会有所不同吗?


1
这个回答解决了你的问题吗?https://dev59.com/5UzSa4cB1Zd3GeqPqNyK - Josh L.
@josh BitConverter看起来很理想,只要通过大小端测试就可以了。 - Graham
(int)BitConverter.ToInt16(new[] {lo, hi}, 0); - Sinatr
@Sinatr 这是远程通信 - 两台机器的字节序可能不同。 - Luaan
1个回答

2

你只使用16位有符号数据。那么为什么要传递(和返回)int而不是short?你抛弃了符号信息,所以它实际上不能用于负数。相反,使用short就可以了 - 额外的类型信息将使你的代码更安全。

byte[] ShortToBytes(short i)
{
  return new byte [] {(byte) ((i >> 8) & 0xff), (byte) (i & 0xff)};
}

short BytesToShort(byte hi, byte lo)
{
  return unchecked((short)((hi << 8) | lo));
}

除了更加清晰和实际运行外,主要优点是您不再能向该方法传递无效值。这总是很好的 :)
哦,我建议保持接口对称 - BytesToShort也应该采用byte[](或其他具有两个字节的结构)。

这会导致负数溢出。 - Graham
不是这样的。我已经测试了负数以及一组随机数。你可能弄混了“hi”和“lo”吗?另一个使用“byte[]”作为“ShortToBytes”和“BytesToShort”的返回值的原因 :) - Luaan
有趣。每次调用 BytesToShorthi > 127 时,我都会遇到溢出问题。这可能与 Checked/Unchecked 设置有关。 - Graham
@Graham哦,你是在LINQPad上测试吗?它默认使用了checked算术运算。但我还是加了显式的unchecked语句,这是一个好习惯 :) - Luaan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接