Question

Je travaille sur un projet où je dois traiter au niveau octet avec des entiers. Comme économiser de l'espace est une considération primordiale, je n'ai besoin que de très petites tailles (et de longueurs variables).

Existe-t-il un moyen de convertir l’int 4096 en 3 octets? ou '1053' dans 2 octets?

Évidemment, je peux le faire manuellement = (octet [0] * 256) + (octet [1]), mais je me demandais s’il existait une option plus facile pour convertir l’int en x octets et revenir?

Était-ce utile?

La solution

Pouvez-vous? Sûr. Cela économisera-t-il de la place? Peut-être, selon le travail que vous voulez faire. Vous devez comprendre que le processeur est 32 bits, ce qui signifie qu'il a 4 registres d'octets, donc c'est comme ça qu'il va vouloir stocker et accéder à des choses. Pour forcer un 3 octets "int" vous devrez le conserver dans un tableau d'octets et l'extraire du tableau en une adresse alignée avant utilisation. Cela signifie que si vous le stockez rapidement, le compilateur le compilera (et vous perdrez toute efficacité que vous pensez avoir créée) ou la lecture et l’écriture seront beaucoup plus lentes.

S'il s'agit d'une application de bureau, en quoi l'économie de l'espace est-elle une considération primordiale, en particulier lorsque vous parlez d'un octet par élément? La pénalité de perf pour l’accès à l’élément peut vous faire oublier l’importance de cet octet.

Je dirais que si ce 1 octet est vraiment important, vous utilisez peut-être le mauvais langage de toute façon. Le nombre d'octets que vous sauvegarderiez si vous n'avez pas installé ni utilisé le CLR est un lot de ces octets.

Note latérale: vous feriez aussi un quart de travail, pas une multiplication (bien que le compilateur y arrive probablement pour vous).

Autres conseils

Juste pour ajouter de la folie, faisons-le en C # en utilisant le vieux truc de l'union dans le style 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;
 }

Ensuite, lorsque vous souhaitez "convertir", procédez comme suit:

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

Mais cela n’aidera vraiment que si vous cherchez à "enregistrer". le coût du décalage d'un bit d'un mot à partir d'un bit. Je n'ai pas examiné le SMIL généré, donc je ne sais pas si cela coûte moins cher par rapport à une autre solution.

Vous pouvez faire un codage entier de longueur variable. L'ancienne méthode d'il y a des années consistait à utiliser le bit haut de chaque octet pour indiquer que l'entier continue sur un autre octet. Donc, vous perdez un bit par octet, mais vous gagnez de petits entiers. Ceci est surtout utile dans le stockage persistant où chaque dernier octet compte.

Exemple: supposons que nous ayons affaire à des entiers non signés, nous aurions

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 prend 1 octet et 128-16383 prend 2 octets, etc ...

Pour des méthodes plus complexes, consultez cette page

.

BitConverter.GetBytes vous obtiendrez les octets.

et

BitConverter.ToInt32 vous obtiendrez un int de 32 bits à partir des octets.

Vous devez changer quelque peu. C'est beaucoup plus facile si vous travaillez avec HEX, car chaque nombre (je veux dire chaque chiffre, mais le chiffre correspond à la base 10, hex git) représente quatre bits.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top