Is there a nice way to split an int into two short

2020-02-26 14:45发布

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

12条回答
等我变得足够好
2楼-- · 2020-02-26 15:02

You might also be interested in StructLayout or unions if you're using c++.

查看更多
成全新的幸福
3楼-- · 2020-02-26 15:07

If you look at the bit representation, then you are correct.

You can do this with unsigned ints though, as they don't have the sign bit.

查看更多
Fickle 薄情
4楼-- · 2020-02-26 15:08

Why not? Lets reduce the number of bits for the sake of simplicity : let's say we have 8 bits of which the left bit is a minus bit.

[1001 0110] // representing -22

You can store it in 2 times 4 bits

[1001] [0110] // representing   -1 and 6

I don't see why it wouldn't be possible, you twice have 8 bits info

EDIT : For the sake of simplicity, I didn't just reduce the bits, but also don't use 2-complementmethod. In my examples, the left bit denotes minus, the rest is to be interpreted as a normal positive binary number

查看更多
三岁会撩人
5楼-- · 2020-02-26 15:10

Int32 num = 70000;

        string str = Convert.ToString(num, 2);
    //convert INT32 to Binary string   
        Int32 strl = str.Length;
    //detect string length


        string strhi, strlo;
    //ifvalue is greater than 16 bit 
        if (strl > 16)
        {
           int lg = strl - 16;
          //dtect bits in higher word 
           strlo = str.Substring(lg, 16);
     ///move lower word string to strlo 

            strhi = str.Substring(0, lg);
   //mov higher word string to strhi

        }
        else
//if value is less than 16 bit
        {
           strhi = "0";
//set higher word zero
           strlo = str;
///move lower word string to strlo 

        }

        Int16 lowword, hiword;
        lowword = Convert.ToInt16(strlo, 2);
        hiword = Convert.ToInt16(strhi, 2);
        ////convert binary string to int16
        }
查看更多
Root(大扎)
6楼-- · 2020-02-26 15:11

You can use StructLayout to do this:

[StructLayout(LayoutKind.Explicit)]
        struct Helper
        {
            [FieldOffset(0)]
            public int Value;
            [FieldOffset(0)]
            public short Low;
            [FieldOffset(2)]
            public short High;
        }

Using this, you can get the full Value as int , and low part, hight part as short.

something like:

var helper = new Helper {value = 12345};
查看更多
Emotional °昔
7楼-- · 2020-02-26 15:14

Unsafe code in C#, overflow doesn't occur, detects endianness automatically:

using System;
class Program
{
    static void Main(String[] args)
    {
        checked // Yes, it works without overflow!
        {
            Int32 original = Int32.MaxValue;
            Int16[] result = GetShorts(original);
            Console.WriteLine("Original int: {0:x}", original);
            Console.WriteLine("Senior Int16: {0:x}", result[1]);
            Console.WriteLine("Junior Int16: {0:x}", result[0]);
            Console.ReadKey();
        }
    }
    static unsafe Int16[] GetShorts(Int32 value)
    {
        byte[] buffer = new byte[4];
        fixed (byte* numRef = buffer)
        {
            *((Int32*)numRef) = value;
            if (BitConverter.IsLittleEndian)
                return new Int16[] { *((Int16*)numRef), *((Int16*)numRef + 1) };
            return new Int16[] { 
                (Int16)((numRef[0] << 8) | numRef[1]),  
                (Int16)((numRef[2] << 8) | numRef[3])
            };
        }
    }
}
查看更多
登录 后发表回答