Comment passer un tableau d'octets par 12 bits
Je veux déplacer le contenu d'un tableau d'octets par 12 bits vers la gauche.
Par exemple, à partir de cette matrice de type uint8_t shift[10]
:
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xBC}
Je voudrais le déplacer vers la gauche en 12 bits:
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAB, 0xC0, 0x00}
OriginalL'auteur Justin Tanner | 2008-08-27
Vous devez vous connecter pour publier un commentaire.
Hourra pour les pointeurs!
Ce code fonctionne en regardant vers l'avant 12 bits de chaque octet et la copie du bon de bits de l'avant. 12 bits est le fond de la moitié (nybble) de l'octet suivant et la moitié supérieure de 2 octets loin.
Bien, je dirais un quart de travail normal de l'opération n'est juste que (appelé dépassement de capacité), et laisse le supplément de bits de la droite ou vers la gauche. Il est assez simple à réaliser si vous voulaient simplement enregistrer l'12 bits avant de commencer à se déplacer. Peut-être que vous voulez une permutation circulaire, de mettre la débordé bits dos, au fond? Peut-être vous voulez realloc le tableau et le rendre plus gros? Retour le débordement de l'appelant? Retourner un booléen si elle est non nulle de données a été débordé? Vous devez définir ce que procéder pour vous.
OriginalL'auteur Mike Haboustak
Voici ma solution, mais encore plus important, mon approche pour résoudre le problème.
J'ai abordé le problème par
Cela m'a montré le modèle:
iL
le faible nybble (demi-octet) dea[i]
iH
être le haut nybble dea[i]
iH = (i+1)L
iL = (i+2)H
Ce schéma reste valable pour tous les octets.
Traduire en C, cela signifie:
Nous avons maintenant faire trois observations:
12 bits
à la fin sera de zéro.a[i+2]
, cela affecte uniquement les deux derniers octetsDonc, nous
N-2 bytes
et en effectuant le calcul général au-dessus deiH = (i+1)L
0
donné
a
avec une longueurN
, nous obtenons:Et là vous l'avez... le tableau est décalé à gauche par
12 bits
. Il pourrait facilement être généralisée à l'évolution de laN bits
, notant qu'il n'y auraM
les instructions d'affectation oùM = number of bits modulo 8
, je crois.La boucle pourrait être rendue plus efficace sur certaines machines par la traduction de pointeurs
et en utilisant le plus grand entier de type de données pris en charge par le CPU.
(J'ai juste tapé ce, alors maintenant serait un bon moment pour que quelqu'un l'examen du code, en particulier depuis peu tourner est très facile de se tromper.)
OriginalL'auteur Mark Harrison
Permet de faire le meilleur moyen de modifier
N
bits dans la gamme de 8 bits entiers.Je pense partir d'ici, vous devez trouver la manière la plus optimale pour rendre l'utilisation de ces données pour se déplacer entiers dans un tableau. Algorithmes génériques serait d'appliquer l'ensemble des entiers changements en partant de la droite du tableau et le déplacement de chaque entier
F
index. Zéro remplissez le nouvellement espaces vides. Puis, enfin, effectuer uneR
de décalage de bits sur tous les indices, à partir de la droite.Dans le cas de changement de
0xBC
parR
bits, vous pouvez calculer le dépassement en procédant de l'une ET au niveau du bit, et de le changer à l'aide de la bitshift opérateur:Gardez à l'esprit que les 4 bits de poids est juste un simple masque: 0x0F ou tout simplement 0b00001111. C'est facile à calculer, à construire, de façon dynamique, ou vous pouvez même utiliser un simple statique de la table de recherche.
J'espère que c'est assez générique. Je ne suis pas bon avec le C/C++ à tous alors peut-être que quelqu'un peut nettoyer ma syntaxe ou d'être plus précis.
Bonus: Si vous êtes astucieux avec votre C vous pourriez être en mesure de fudge plusieurs indices de tableau en une seule 16, 32 ou même 64 bits d'un entier et d'effectuer les changements. Mais c'est prabably pas très portable et je le recommande à cet égard. Juste une optimisation possible.
OriginalL'auteur Joseph Pecoraro
Ici une solution de travail, à l'aide de variables temporaires:
Appeler cette fonction à 3 fois pour un de 12 de décalage de bits.
Mike solution peut-être plus vite, en raison de l'utilisation de variables temporaires.
OriginalL'auteur Justin Tanner
La version 32 bits... 🙂 Poignées 1 <= nombre <= num_words
from
et de la lecture dans la même instruction provoque un comportement indéfini. Même si ce n', l'ordre d'évaluation des deux occurrences defrom
serait pas défini et il n'est pas garanti arriver dans le bon ordre.OriginalL'auteur DMC
@Joseph, notez que les variables sont les 8 bits de large, tandis que le passage est de 12 bits de large. Votre solution ne fonctionne que pour le N <= taille variable.
Si vous pouvez supposer que votre tableau est un multiple de 4, vous pouvez convertir le tableau en un tableau d'un uint64_t et ensuite travailler sur. Si ce n'est pas un multiple de 4, vous pouvez travailler en 64 bits morceaux sur autant que vous le pouvez et de travailler sur le reste, un par un.
Cela peut être un peu plus de codage, mais je pense qu'il est plus élégant de la fin.
OriginalL'auteur Nathan Fellman
Il y a un couple de pointe-des cas qui font de ce un pur problème:
Voici une solution simple qui passe en boucle sur le tableau de copier le bas de grignoter de l'octet suivant dans son haut afin de grignoter, et le haut afin de grignoter de la next-next (+2) octet dans son bas de grignoter. Pour enregistrer un déréférencement le " look-ahead pointeur deux fois, elle entretient une à deux éléments de la mémoire tampon avec le "dernier" et "prochain" octets:
Pensez à la limite des cas, ce qui activer successivement plusieurs parties de la fonction:
length
est égal à zéro, nous renflouer sans toucher à la mémoire.length
est l'un, nous avons fixé le seul et unique élément à zéro.length
est deux, nous avons mis le haut afin de grignoter du premier octet de poids faible de l'ordre de grignoter le deuxième octet (qui est, les bits 12 à 16), et le deuxième octet à zéro. Nous n'avons pas d'activer la boucle.length
est plus grand que deux, nous avons touché la boucle, brouiller les octets entre les deux éléments de la mémoire tampon.Si l'efficacité est votre but, la réponse dépend probablement en grande partie sur votre machine de l'architecture. Habituellement, vous devez maintenir les deux éléments de la mémoire tampon, mais la poignée d'une machine word (32/64 bits entier non signé) à la fois. Si vous êtes à la vitesse d'un grand nombre de données, il sera peut être utile de traiter les premiers octets comme un cas particulier de sorte que vous pouvez obtenir votre machine word pointeurs mot-alignés. La plupart des Processeurs d'accès mémoire plus efficacement si l'accès de l'automne sur la machine, les limites des mots. Bien sûr, la fuite d'octets doivent être traitées spécialement trop afin de ne pas toucher à la mémoire passé la fin du tableau.
OriginalL'auteur Dominic Cooney