10
votes

C # Langue: Changer les quatre premiers bits dans un octet

Afin d'utiliser un octet à son potentiel le plus complet, je tente de stocker deux valeurs uniques dans un octet: une dans les quatre premiers bits et une autre dans les quatre secondes de quatre bits. Cependant, j'ai constaté que, tandis que cette pratique permet une allocation de mémoire optimisée, elle permet de modifier les valeurs individuelles stockées dans l'octet difficile.

Dans mon code, je souhaite modifier le premier ensemble de quatre bits dans un octet tout en maintenant la valeur des quatre secondes de quatre bits de même octet. Bien que les opérations bitwises me permettent de récupérer et de manipuler facilement les quatre premières valeurs bit, je trouve qu'il est difficile de concaténer cette nouvelle valeur avec le deuxième ensemble de quatre bits dans un octet. La question est, comment puis-je effacer les quatre premiers bits d'un octet (ou, plus précisément, définissez-les tous les zéro) et ajoutez le nouvel ensemble de 4 bits pour remplacer les quatre bits qui ont été effacés, préservant ainsi les 4 derniers bits dans un octet tout en changeant les quatre premiers?

Voici un exemple: xxx


1 commentaires

Pourquoi fais-tu ça? Pensez-vous que cela vous procurera une meilleure performance?


9 Réponses :


20
votes

Utiliser le bitwise et ( & code>) pour effacer les anciens bits, décaler les nouveaux bits à la position correcte et le bit bit ou ( | code>) ensemble:

                       value        : abcdefgh
                       newFirstFour : 0000xyzw

                               0xF  : 00001111
                       value & 0xF  : 0000efgh
                  newFirstFour << 4 : xyzw0000
(value & 0xF) | (newFirstFour << 4) : xyzwefgh


2 commentaires

Fonctionne comme un charme. Mille mercis.


@OOOver Joe, puisque cela a travaillé pour vous, vous devez l'accepter comme réponse à votre question.



2
votes

Vous vous masquez d'abord les quatre octets élevés en utilisant valeur et 0xf code>. Ensuite, vous déplacez les nouveaux bits sur les quatre bits hauts à l'aide de Newfirstfour et vous les combinez enfin à l'aide de binaire ou.

public void changeHighFourBits(byte newHighFour)
{
    value=(byte)( (value & 0x0F) | (newFirstFour << 4));
}

public void changeLowFourBits(byte newLowFour)
{
    value=(byte)( (value & 0xF0) | newLowFour);
}


0 commentaires

0
votes

Un look rapide indiquerait qu'un peu et peut être atteint à l'aide de l'opérateur et de l'exploitant. Donc, pour supprimer les quatre premiers octets, vous devriez pouvoir faire:

byte value1=255; //11111111
byte value2=15; //00001111

return value1&value2;


2 commentaires

Cela ne résout que la moitié du problème. Il efface les hauts bits, mais ne les remplace pas.


Le point est que vous pouvez ensuite les remplacer avec quelque chose d'autre de la même manière.



0
votes

En supposant que NEWVAL contienne la valeur que vous souhaitez stocker dans Origval. Faites ceci pour les 4 bits les moins significatifs: xxx

et ceci pour les 4 bits les plus significatifs: xxx


2 commentaires

Cela remplace les quatre bits bas, mais si je comprends bien, l'OP veut changer les quatre bits élevés.


Il a dit "les quatre premiers" qui est ambigu; Personnellement, je l'interprétons comme les quatre inférieurs comme Petar.



1
votes

Je ne suis pas vraiment sûr de ce que votre méthode est censée faire, mais voici quelques méthodes pour vous:

void setHigh(ref byte b, byte val) {
    b = (b & 0xf) | (val << 4);
}

byte high(byte b) {
    return (b & 0xf0) >> 4;
}

void setLow(ref byte b, byte val) {
    b = (b & 0xf0) | val;
}

byte low(byte b) {
    return b & 0xf;
}


0 commentaires

0
votes

Je sais que vous avez demandé spécifiquement de supprimer les quatre premiers bits, qui a été répondu à plusieurs reprises, mais je voulais souligner que si vous avez deux valeurs <= décimal 15, vous pouvez les combiner dans 8 bits simplement avec cette : xxx

Le résultat sera xxxxyyyy xxx

et c'est ce que vous semblez essayer de faire.


0 commentaires

12
votes

Quand je dois faire un bit-twiddling comme ça, je fais une structure réadonnée pour le faire pour moi. Un entier à quatre bits s'appelle Nybble, bien sûr: xxx

puis ajouter des conversions implicites entre Twonybbles et octets. Maintenant, vous pouvez simplement traiter n'importe quel octet comme ayant un octet élevé et bas sans mettre tout ce laid de la vilaine Twiddling dans votre code principal.


2 commentaires

@Minitech: Wikipedia dit que Nybble est une orthographe alternative courante.


Peut-être qu'un jour, je peux convaincre assez de personnes d'envisager un entier deux bits pour être un NYP. :)



0
votes

Voici un seul code, mais je pense que les réponses précédentes le feront pour vous. Il s'agit simplement de montrer une sorte de code de test pour copier et passer dans un projet de console simple (la méthode des bulles de bulletin d'aide à l'aide): xxx


0 commentaires

1
votes
public int SplatBit(int Reg, int Val, int ValLen, int Pos)
{
    int mask = ((1 << ValLen) - 1) << Pos;
    int newv = Val << Pos;
    int res = (Reg & ~mask) | newv;
    return res;            
}
Example: 
Reg = 135 
Val = 9 (ValLen = 4, because 9 = 1001) 
Pos = 2
135       = 10000111   
9         =     1001
9 << Pos  =   100100
Result    = 10100111

0 commentaires