在 C# 中将 Short[2] 转换为 Int32

Convert a Short[2] to Int32 in C#

我在 C# 中有一个短数组,我需要转换 Int32 中的两个元素。我写的代码如下

uint pesoparz = (Convert.ToUInt16(values[0]));
Int32 pesotot = Convert.ToInt32(pesoparz *65536 + Convert.ToUInt16(values[1]));

其中 values[] 是短数组,pesotot 是我想要获得的 Int32。它有效,但不幸的是,当值 [1] 超过 2^15 时,我得到系统溢出异常。

为什么会出现异常?

这个最好用shift and or,用unchecked防止溢出错误:

int result = unchecked((int)(((uint)values[0] << 16) | values[1]));

您正在寻找 unchecked 关闭 IntegerOverflow:

  short left = -123;
  short right = -456;

  int result = unchecked(BitConverter.IsLittleEndian 
    ? (UInt16)left << 16 | (UInt16)right 
    : (UInt16)right << 16 | (UInt16)left);

您可能想要使用 BitConverter.IsLittleEndian 来检测 short 部分应该组合成 int 的顺序。

试试这个

uint pesoparz = (Convert.ToUInt16(values[0]));
Int32 pesotot = Convert.ToInt32(pesoparz *65536 + Convert.ToUInt32(values[1]));

您似乎已达到上限

short[] arr = new short[] { 512, -32767 };

int ival = ((int)arr[0] * 65536) + ((int)arr[1] & 0xffff);
// also:
// ival = ((int)arr[0] << 16) | ((int)arr[1] & 0xffff); 
Console.WriteLine(ival);

这给出了 33587201 的正确结果。 诀窍(如果有的话)是使用强制转换将短裤变成整数,然后屏蔽掉不需要的部分(在本例中为符号扩展)。这既不需要 Convert 也不需要 unchecked.

您可以使用按位运算符:

short[] parts = new short[2];
parts[0] = 1;
parts[1] = 2;

uint result = 0;

result = (ushort)parts[0] << 16 | (ushort)parts[1];

结果将是 0x00010002(十六进制)或 65538(十进制)。

您确定值数组的每个值都适合 Int16 吗?

如果没有,那么即使取消勾选,结果也不是你想要的。首先,如果 values[0] 或 values1 大于 Int16.

中的容量,您必须决定要做什么

您的决定取决于值的含义。 values[0] 是否代表结果 Int32 的最高 16 位,而 values[0] 代表最低 16 位?

在这种情况下,如果 values[0] 或 values1 大于 Int16.MaxValue,您应该抛出 ArgumentException。之后你的代码就很简单了:

if (values[0] > Int16.MaxValue || values[1] > Int16.MaxValue)
    throw new ArgumentException("values should fit in two bytes");
Int32 result = values[0] << 0x10000 + values[1];
return result;

也可能是允许两个值都大于0x10000,如果数字太大,你自己想想你想要什么结果。

顺便说一下,如果您的每个值都代表 Int32 的一半,请考虑调换值[0] 和值1 的含义。几乎总是最低有效位 (LSB) 在 [0] 中,而最高有效位 (MSB) 在 1 中。如果按照这个约定,就不用自己写这些转换器了,可以使用BitConverter class

Int32 original = 0x12345678;
byte[] bytes = BitConverter.GetBytes(original);
foreach (var b in bytes)
    Console.WriteLine(b.ToString("02X"); // write in two digit hex format
// will write lines with 78 56 34 12
Int16[] Values = new Int16[]
{
    BitConverter.ToInt16(bytes),     // LSB
    BitConverter.ToInt16(bytes, 2),  // MSB
};
Int32 result = (Int32)values[0] + (Int32)values[1] << 0x10000;
Debug.Assert(original == result);