1

long 値と byte[] 値のシリアル化のために作成した、以下に示す 2 つの関数があります。

    public static byte[] LongToByte(long Value)
    {
        byte[] Output = new byte[8];
        Output[0] = (byte)Value;
        Output[1] = (byte)(Value >> 8);
        Output[2] = (byte)(Value >> 16);
        Output[3] = (byte)(Value >> 24);
        Output[4] = (byte)(Value >> 32);
        Output[5] = (byte)(Value >> 40);
        Output[6] = (byte)(Value >> 48);
        Output[7] = (byte)(Value >> 56);
        return Output;
    }

    public static long LongFromByte(byte[] Value)
    {
        long Output = Value[0];
        Output += ((long)Value[1] << 8);
        Output += ((long)Value[2] << 16);
        Output += ((long)Value[3] << 24);
        Output += ((long)Value[4] << 32);
        Output += ((long)Value[5] << 40);
        Output += ((long)Value[6] << 48);
        Output += ((long)Value[7] << 56);
        return Output;
    }

上記の方法を使用すると、それらを使用しているすべてのプラットフォームでエンディアンが同じままになります。

または、コードを処理するシステムのエンディアンに基づいて、またはいずれかの結果が変化しますか?

すべてに感謝します。

4

2 に答える 2

2

デフォルトのものはかなり良く、いくつかの最適化があるので、カスタムバイナリ変換を行うことは避けます。

以下を使用してシステムのエンディアンを確認することをお勧めします。

var isLittleEndian = BitConverter.IsLittleEndian;

また、現在のエンディアンに問題がある場合にのみカスタム変換を使用します(または、Array.Reverse(bytes)を使用してバイトを逆にすることができます)。

パフォーマンスが必須である場合(それについては本当に妄想的です)、カスタムの逆バイトアルゴリズム(ルックアップテーブルまたはビットの交換を使用)を実装するか、逆の順序でバイトをlongに変換する安全でないコードを実装する(BitConverterソースを参照)か、または単にビット単位の演算子を使用して現在のコードを改善します。

編集:カスタムシリアライザーのILコードを調べて([Telerik Just Decompile](http://www.telerik.com/products/decompiler.aspxを使用して利便性を高める))、longからbyteへのキャストはconv.u1命令。

MSDNによると:

ある整数型を別の整数型に変換してオーバーフローが発生した場合、上位ビットは切り捨てられます。

これを考慮すると、コードはビッグエンディアンシステムで同じ出力を生成します。

于 2012-11-07T02:05:53.047 に答える
1

はい、各バイトを個別に抽出して配列に格納しているためです。たとえば、'Output[0]' は常に、変換する数値の下位 8 ビットです。その後、配列を (ディスク ファイルまたはトランスポート経由で) 書き込むと、バイトは常に指定した順序になります。

または、 BitConverterクラスのドキュメントの備考セクションで説明されている手法の使用を検討することもできます。

于 2012-11-07T01:53:05.527 に答える