Frage

ich an einem Projekt arbeite, wo ich mit ganzen Zahlen auf Byte-Ebene befassen muß. Da platzsparend eine primäre Überlegung ist, ich brauche nur sehr klein (und variabler Länge Ints).

Gibt es eine Möglichkeit, dass ich den int drehen kann ‚4096‘ in 3 Bytes? oder '1053' in einen 2 Byte?

Offensichtlich ich CNA tut es manuell = (byte [0] * 256) + (byte [1]), aber ich frage mich, ob es eine einfachere Möglichkeit ist, die int in x Bytes und wieder zurück zu konvertieren?

War es hilfreich?

Lösung

Können Sie? Sicher. Wird es keinen Platz sparen? Vielleicht, je nachdem, wie viel Arbeit Sie tun möchten. Sie müssen verstehen, dass der Prozessor 32-Bit ist, hat es 4 Byte Register Bedeutung, so das ist, wie es zu speichern und den Zugang Dinge zu wollen, geht. Um zu erzwingen, einen 3-Byte „int“ Sie müssen sie halten in einem Byte-Array, und entpacken Sie es aus dem Array zu einer ausgerichteten Adresse vor dem Gebrauch. Das bedeutet, dass, wenn Sie es kurz zu speichern, wird der Compiler entweder Pad es (und Sie jede Effizienz verlieren werden Sie denken, Sie haben erstellt) oder es wird ein Los langsamer lesen und schreiben sein.

Wenn es sich um eine Desktop-Anwendung, wie genau Raum spart eine primäre Überlegung, vor allem, wenn 1 Byte pro Element sprechen? Die perf Strafe für Elementzugriff können Sie ändern etwas dagegen, wie wichtig, dass ein Byte ist.

Ich würde argumentieren, dass, wenn das 1 Byte ist wirklich wichtig, dass vielleicht, nur vielleicht, ich ist die falsche Sprache sowieso verwenden. Die Anzahl der Bytes, die Sie speichern würde meine nicht installiert haben und die CLR in erster Linie verwendet, ist eine Los dieser Bytes.

Randbemerkung:. Sie würden auch eine Verschiebung tun, nicht eine Multiplikation (obwohl der Compiler wahrscheinlich für Sie da bekommen würde)

Andere Tipps

Nur für zusätzlichen Wahnsinn, sie tut es in C # den alten C-Stil Vereinigung Trick:

[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;
 }

Und dann, wenn Sie wollen "konvertieren", dies zu tun:

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

Aber das wirklich hilft nur, wenn Sie schauen zu „retten“ die Kosten für die Bit-Verschiebung von einem Wort, ein einziges Byte aus. Ich habe nicht an dem generierten SMIL sieht, so dass ich weiß nicht, ob dies irgendein billiger im Vergleich zu jeder anderen Lösung.

Sie können mit variabler Länge integer Codierung tun. Die alte Methode von Jahren war das hohe Bit jedes Byte zu verwenden, um anzuzeigen, dass die ganze Zahl auf ein anderes Byte fortgesetzt. So verlieren Sie ein Bit pro Byte, aber kleine ganze Zahlen gewinnen. Dies ist vor allem nützlich bei persistenten Speicher, wo alle letzte Byte zählt.

Beispiel: Angenommen, wir mit unsignierten ganzen Zahlen zu tun haben, müssten wir

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 

so 0-127 nehmen 1 Byte und 128-16383 dauert 2 Bytes, etc ...

Für komplexere Möglichkeiten, dies zu tun Besuche dieser Seite

BitConverter.GetBytes erhalten Sie die Bytes erhalten.

und

BitConverter.ToInt32 finden Sie eine 32-Bit-int aus den Bytes erhalten.

Sie haben einige Bitverschiebung zu tun. Es ist viel einfacher, wenn Sie mit HEX arbeiten, da jede Zahl (ich meine jede Ziffer, aber Ziffer ist für die Basis 10, hex git) vier Bits darstellen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top