Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a nice way to split an int into two shorts (.NET)?

Tags:

c#

.net

math

vb.net

I think that this is not possible because Int32 has 1 bit sign and have 31 bit of numeric information and Int16 has 1 bit sign and 15 bit of numeric information and this leads to having 2 bit signs and 30 bits of information.

If this is true then I cannot have one Int32 into two Int16. Is this true?

Thanks in advance.

EXTRA INFORMATION: Using Vb.Net but I think that I can translate without problems a C# answer.

What initially I wanted to do was to convert one UInt32 to two UInt16 as this is for a library that interacts with WORD based machines. Then I realized that Uint is not CLS compliant and tried to do the same with Int32 and Int16.

EVEN WORSE: Doing a = CType(c And &HFFFF, Int16); throws OverflowException. I expected that statement being the same as a = (Int16)(c & 0xffff); (which does not throw an exception).

like image 784
Ignacio Soler Garcia Avatar asked Dec 09 '09 11:12

Ignacio Soler Garcia


People also ask

How do you divide two digit integers?

int i = 45; // or anything you want int firstDigit = i / 10; int secondDigit = i % 10; It's quite simple really.

How do I convert string to int to split?

The string. split() method is used to split the string into various sub-strings. Then, those sub-strings are converted to an integer using the Integer. parseInt() method and store that value integer value to the Integer array.


2 Answers

This can certainly be done with no loss of information. In both cases you end up with 32 bits of information. Whether they're used for sign bits or not is irrelevant:

int original = ...;

short firstHalf = (short) (original >> 16);
short secondHalf = (short) (original & 0xffff);

int reconstituted = (firstHalf << 16) | (secondHalf & 0xffff);

Here, reconstituted will always equal original, hence no information is lost.

Now the meaning of the signs of the two shorts is a different matter - firstHalf will be negative iff original is negative, but secondHalf will be negative if bit 15 (counting 0-31) of original is set, which isn't particularly meaningful in the original form.

like image 51
Jon Skeet Avatar answered Oct 19 '22 13:10

Jon Skeet


This should work:

int original = ...;
byte[] bytes = BitConverter.GetBytes(original);
short firstHalf = BitConverter.ToInt16(bytes, 0);
short secondHalf = BitConverter.ToInt16(bytes, 2);

EDIT:

tested with 0x7FFFFFFF, it works

byte[] recbytes = new byte[4];
recbytes[0] = BitConverter.GetBytes(firstHalf)[0];
recbytes[1] = BitConverter.GetBytes(firstHalf)[1];
recbytes[2] = BitConverter.GetBytes(secondHalf)[0];
recbytes[3] = BitConverter.GetBytes(secondHalf)[1];
int reconstituted = BitConverter.ToInt32(recbytes, 0);
like image 16
Agg Avatar answered Oct 19 '22 12:10

Agg