将long转换为两个int以进行重构

Kei*_*ler 9 c# int

我需要将一个参数作为两个int参数传递给Telerik报告,因为它不能接受Long参数.将long转换为两个整数并在不丢失数据的情况下重建它的最简单方法是什么?

MGw*_*nne 13

使用遮蔽和移动是最好的选择.根据文档,long保证为64位和int 32位,因此您可以将位掩码为两个整数然后重新组合.

看到:

    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();
    }
Run Code Online (Sandbox Code Playgroud)

注意整个按位操作的使用.这避免了在使用可能使用负数或舍入误差时可能发生的加法或其他数值运算时可能遇到的问题.

注意如果你能够使用无符号整数,你可以在上面的代码中用uint替换int(在这种情况下,这总是更好,因为它更清楚地发生了什么比特).


Jef*_*ado 6

在C#中进行位操作有时会很尴尬,特别是在处理有符号值时.无论何时计划进行位操作,都需要使用无符号值.不幸的是,它不会产生最好看的代码.

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));
Run Code Online (Sandbox Code Playgroud)

如果你想要一个更好的方法来做这个,获取long的原始字节并从字节中获取相应的整数.转换到表示/从表示转换不会发生太大变化.

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);
Run Code Online (Sandbox Code Playgroud)