4

I am working on a project where I need to deal at the byte level with integers. Since saving space is a primary consideration, I only need very small (and variable length ints).

Is there a way that I can turn the int '4096' into 3 bytes? or '1053' into a 2 bytes?

Obviously I cna do it manually = (byte[0] * 256) + (byte[1]), but i was wondering if there is an easier option to convert the int into x bytes and back again?

4

5 に答える 5

14

あなたはできる?もちろん。スペースを節約できますか?たぶん、あなたがやりたい仕事の量に応じて。プロセッサは32ビットであり、4バイトのレジスタがあることを理解する必要があります。そのため、プロセッサは物事を保存してアクセスする必要があります。3バイトの「int」を強制するには、それをバイト配列に保持し、使用する前に配列から整列されたアドレスに抽出する必要があります。つまり、短く保存すると、コンパイラーがそれを埋めてしまうか(作成したと思う効率が失われる)、読み取りと書き込みが大幅に遅くなります。

これがデスクトップアプリの場合、特に要素ごとに1バイトを話す場合、スペースを節約することが主な考慮事項です。要素アクセスのパフォーマンスペナルティにより、その1バイトがどれほど重要であるかについて気が変わる可能性があります。

その1バイトが本当に重要である場合、それはおそらく、おそらく、とにかく間違った言語を使用していると私は主張します。そもそもCLRをインストールして使用しないことで節約できるバイト数は、それらのバイトの多くです。

補足:乗算ではなくシフトも実行します(ただし、コンパイラーがそこに到達する可能性があります)。

于 2009-01-15T05:30:23.460 に答える
5

可変長整数エンコーディングを行うことができます。数年前の古い方法では、各バイトの上位ビットを使用して、整数が別のバイトに続くことを示していました。したがって、バイトごとに1ビットが失われますが、小さな整数が得られます。これは、最後のすべてのバイトが重要になる永続ストレージで主に役立ちます。

例:符号なし整数を扱っていると仮定すると、次のようになります。

int  binary
0                       00000000
1                       00000001
...  
127                     01111111
128            00000001 10000000
129            00000001 10000001
...
255            00000001 11111111
256            00000010 10000000
...
16383          01111111 11111111
16384 00000001 10000000 10000000 

したがって、0-127は1バイトを取り、128-16383は2バイトを取ります。

これを行うためのより複雑な方法については、このページをチェックしてください

于 2009-01-15T05:57:28.320 に答える
5

追加の狂気のために、古いCスタイルのユニオントリックを使用してC#でそれを実行しましょう:

[StructLayout(LayoutKind.Explicit)]
struct OddUnion
{
    /* The 32-bit integer value */
    [FieldOffset(0)]
    public int IntegerValue;

    /* The bytes that overlap with it */
    [FieldOffset(0)]
    public byte Byte1;
    [FieldOffset(1)]
    public byte Byte2;
    [FieldOffset(2)]
    public byte Byte3;
    [FieldOffset(3)]
    public byte Byte4;
 }

そして、「変換」したい場合は、次のようにします。

OddUnion myOddUnion;
myOddUnion.IntegerValue = 4096;
Byte secondByte = myOddUnion.Byte1;

しかし、これは、ワードから1バイトをビットシフトアウトするコストを「節約」しようとしている場合にのみ役立ちます。生成されたSMILを見たことがないので、これが他のソリューションと比較して安いかどうかはわかりません。

于 2009-01-15T06:15:16.130 に答える
3

BitConverter.GetBytesあなたにバイトを取得します。

BitConverter.ToInt32バイトから32ビット整数を取得します。

于 2009-01-15T05:31:26.610 に答える
1

あなたはいくつかのビットシフトをしなければなりません。すべての数値(つまり、すべての桁を意味しますが、桁は基数10、16進数)は4ビットを表すため、HEXを使用する場合は非常に簡単です。

于 2009-01-15T05:31:13.473 に答える