繁体   English   中英

在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时,我得到系统溢出异常。

为什么会发生异常?

您正在寻找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的顺序。

您可以使用按位运算符:

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

uint result = 0;

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

结果将是十六进制的0x00010002或十进制的65538

最好使用shift和或为此,并使用unchecked来防止溢出错误:

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

试试这个

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

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

如果没有,那么即使你取消选中,结果也不是你想要的。 首先,如果值[0]或值1大于Int16中的拟合,则必须决定该怎么做。

您的决定取决于值的含义。 值[0]表示结果Int32的最高16位,值[0]表示最低16位吗?

在这种情况下,如果值[0]或值1大于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类

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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM