Convert Short [2] to Int32 in C #

I have a short array in C # and I need to convert two elements to Int32. The code I wrote is as follows

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

where the values ​​[] is a short array, and the pesoott is Int32, which I would like to get. This works, but unfortunately when the value [1] exceeds 2 ^ 15, I get a system overflow exception.

Why is an exception raised?

+6
source share
6 answers

You are looking for unchecked that disables IntegerOverflow :

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

You can use BitConverter.IsLittleEndian to determine the order in which the short parts should be combined into an int .

+2
source

You can use bitwise operators:

 short[] parts = new short[2]; parts[0] = 1; parts[1] = 2; uint result = 0; result = (ushort)parts[0] << 16 | (ushort)parts[1]; 

The result will be 0x00010002 in hexadecimal or 65538 in decimal format.

+2
source

It is best to use a shift and / or for this, and use unchecked to prevent an overflow error:

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

try it

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

You seem to have reached the limit

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

This gives the correct result 33587201 . The trick, if one exists, is to use casting to get the shorts in an int and then mask the parts you don't need (in this case, the sign extension). This does not require Convert and unchecked .

0
source

Are you sure that each value in your array of values ​​corresponds to Int16?

If not, then even if you uncheck the box, the result is not the one you want. First you will need to decide what to do if the values ​​[0] or the value 1 is greater than what is suitable for Int16.

Your decision depends on what the meanings mean. Are the values ​​[0] representing the highest 16 bits of your resulting Int32 and the values ​​[0] the lower 16 bits?

In this case, you should throw an ArgumentException if [0] or 1 is greater than Int16.MaxValue. After that, your code is simple:

 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; 

It can also mean that it is allowed that both values ​​are greater than 0x10000, you should think about yourself what you want, as a result, if the numbers are too large.

By the way, if your values ​​represent one half of Int32, consider switching the values ​​of [0] and 1 . Almost always, the least significant bits (LSB) are at [0], and the most significant bits (MSB) are at 1 . If you follow this convention, you do not need to write these converters yourself, you can use the 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); 
0
source

Source: https://habr.com/ru/post/1013991/


All Articles