Converting a long and two int for reconstruction

I need to pass the parameter as two int parameters to the Telerik report, since it cannot accept long parameters. What is the easiest way to split long into two ints and restore it without data loss?

+8
c # int
source share
6 answers

Using masking and panning is your best bet. long is guaranteed to be 64 bits and int 32 bits, according to the documentation, so you can mask the bits into two integers and then recombine.

Cm:

static int[] long2doubleInt(long a) { int a1 = (int)(a & uint.MaxValue); int a2 = (int)(a >> 32); return new int[] { a1, a2 }; } static long doubleInt2long(int a1, int a2) { long b = a2; b = b << 32; b = b | (uint)a1; return b; } static void Main(string[] args) { long a = 12345678910111213; int[] al = long2doubleInt(a); long ap = doubleInt2long(al[0],al[1]); System.Console.WriteLine(ap); System.Console.ReadKey(); } 

Pay attention to the use of bitwise operations. This avoids the problems that may arise when using addition or other numerical operations that may arise using negative numbers or rounding errors.

Please note that you can replace int with uint in the above code if you can use unsigned integers (this is always preferable in a similar situation, since it is much clearer what happens to bits).

+11
source share

Performing bit manipulation in C # can sometimes be inconvenient, especially when it comes to signed values. You must use unsigned values ​​whenever you plan to manipulate bits. Unfortunately, this will not give the most beautiful code.

 const long LOW_MASK = ((1L << 32) - 1); long value = unchecked((long)0xDEADBEEFFEEDDEAD); int valueHigh = (int)(value >> 32); int valueLow = (int)(value & LOW_MASK); long reconstructed = unchecked((long)(((ulong)valueHigh << 32) | (uint)valueLow)); 

If you want a more convenient way to do this, get the raw bytes over time and get the corresponding numbers from the bytes. Converting to / from representations does not change much.

 long value = unchecked((long)0xDEADBEEFFEEDDEAD); byte[] valueBytes = BitConverter.GetBytes(value); int valueHigh = BitConverter.ToInt32(valueBytes, BitConverter.IsLittleEndian ? 4 : 0); int valueLow = BitConverter.ToInt32(valueBytes, BitConverter.IsLittleEndian ? 0 : 4); byte[] reconstructedBytes = BitConverter.IsLittleEndian ? BitConverter.GetBytes(valueLow).Concat(BitConverter.GetBytes(valueHigh)).ToArray() : BitConverter.GetBytes(valueHigh).Concat(BitConverter.GetBytes(valueLow)).ToArray(); long reconstructed = BitConverter.ToInt64(reconstructedBytes, 0); 
+3
source share
  long x = long.MaxValue; int lo = (int)(x & 0xffffffff); int hi = (int)((x - ((long)lo & 0xffffffff)) >> 32); long y = ((long)hi << 32) | ((long)lo & 0xffffffff); Console.WriteLine(System.Convert.ToString(x, 16)); Console.WriteLine(System.Convert.ToString(lo, 16)); Console.WriteLine(System.Convert.ToString(hi, 16)); Console.WriteLine(System.Convert.ToString(y, 16)); 
+2
source share

For unigned, the following will work:

 ulong value = ulong.MaxValue - 12; uint low = (uint)(value & (ulong)uint.MaxValue); uint high = (uint)(value >> 32); ulong value2 = ((ulong)high << 32) | low; 
+2
source share
 long spork = 0x7f1234567f125953; int[] ints = new int[2]; ints[0] = (int)(spork >> 32); ints[1] = (int)(spork & (long)0xFFFFFFFF); long reconstructed = ((long)ints[0] << 32) + (long)ints[1]; 

Is this work for you?

+1
source share

Converting it to and from a string would be much simpler than converting two to and from an int pair. Is this an option?

 string myStringValue = myLongValue.ToString(); myLongValue = long.Parse(myStringValue); 
+1
source share

All Articles