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