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
I did not use bitwise operators but for unsigned values, this may work:
public (ushort, ushort) SplitToUnsignedShorts(uint value)
{
ushort v1 = (ushort) (value / 0x10000);
ushort v2 = (ushort) (value % 0x10000);
return (v1, v2);
}
Or an expression body version of it:
public (ushort, ushort) SplitToUShorts(uint value)
=> ((ushort)(value / 0x10000), (ushort)(value % 0x10000));
As for signs, you have to decide how you want to split the data. There can only be 1 negative output out of two. Remember a signed value always sacrifices one bit to store the negative state of the number. And that essentially 'halves' the maximum value you can have in that variable. This is also why uint can store twice as much as a signed int.
As for encoding it to your target format, you can either choose make the second number an unsigned short, to preserve the numerical value, or you can manually encode it such that the one bit now represent the sign of that value. This way although you will lose the originally intended numeric value for a sign bit, you don't lose the original binary data and you can always reconstruct it to the original value.
In the end it comes down to how you want to store and process that data. You don't lose the bits, and by extension, the data, as long as you know how to extract the data from (or merge to) your encoded values.