再構築のためにlongを2 intに変換します

c# int
再構築のためにlongを2 intに変換します

長いパラメーターを受け入れることができないため、Telerikレポートにパラメーターを2つのintパラメーターとして渡す必要があります。 longを2つのintに分割し、データを失うことなく再構築する最も簡単な方法は何ですか?

  9  3


ベストアンサー

マスキングとシフトを使用するのが最善の策です。 ドキュメントによると、longは64ビットとint 32ビットであることが保証されているため、ビットを2つの整数にマスクしてから再結合できます。

See:

    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();
    }

全体にわたってビット演算の使用に注意してください。 これにより、負の数または丸め誤差を使用して発生する可能性のある加算またはその他の数値演算を使用するときに発生する可能性のある問題を回避できます。

符号なし整数を使用できる場合は、上記のコードでintをuintに置き換えることができます(このような状況では、ビットで何が起こっているかがずっと明確であるため、これは常に望ましいことです)。

12


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

これを行うためのより良い方法が必要な場合は、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);

6


        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


無点火の場合、以下が機能します。

ulong value = ulong.MaxValue - 12;
uint low = (uint)(value & (ulong)uint.MaxValue);
uint high = (uint)(value >> 32);

ulong value2 = ((ulong)high << 32) | low;

2


文字列への変換と文字列からの変換は、2つのintのペアからの変換よりもはるかに簡単です。 これは選択肢ですか?

string myStringValue = myLongValue.ToString();

myLongValue = long.Parse(myStringValue);

1


タイトルとURLをコピーしました