-1
votes

C: Opération opposée à la gauche-shift

Supposons l'opération suivante:

1 << bit

bit peut prendre des valeurs de 0 et plus. Connaissant le résultat de l'opération de décalage de gauche, comment puis-je dériver la valeur bit

Je sais que le changement de bit gauche est équivalent à la multiplication du nombre d'origine (1 dans mon exemple) par une puissance de 2, par exemple. :

1 << 0 => 1 * 2 ^ 0 = 1

1 << 1 => 1 * 2 ^ 1 = 2

et ainsi de suite.

Alors, comment puis-je obtenir la valeur de puissance?


6 commentaires

Faites un bit de droite à droite jusqu'à ce que la valeur soit 1 ?


Bit est la base de journal 2.


Le changement de gauche par n Les bits provoquent la valeur de perdre n bits de gauche, donc je pense qu'il ne peut pas être inversé


S'il vous plaît Modifier Votre question à clarifier: Est-ce que toujours 1 qui est déplacé? Que l'opération est toujours 1 << n , avec 1 sur le côté gauche? La réponse à votre question dépend beaucoup de cela. De plus, peut n jamais être plus grand que la largeur de bit possible de int ?


Il y a des algorithmes rapides pour log2, par ex. ici .


Est-ce que cela répond à votre question? Informatique rapide de log2 pour les entiers 64 bits


4 Réponses :


1
votes

Inverser l'opération.

Prenez la valeur résultante et passez à droite par un, comptant chaque fois que vous le faites, jusqu'à ce que vous obteniez 1. p>

unsigned int val = 1 << bit;
int count = 0;
while (val > 1) {
    val >>= 1;
    count++;
}


4 commentaires

Bien sûr, ce n'est que si aucune forte bite n'a été décalée de la fin.


@CHARLESDUFFY L'OP stipule que c'est toujours 1 << n , c'est-à-dire pas de bits élevés.


Dans le corps, oui, mais le titre indique une question plus générale. Il est difficile de dire si l'exemple dans le corps est ce qu'ils veulent demander, ou juste un accident d'une imagination insuffisante dans le développement de ladite exemple. (Ce n'est pas vraiment rare ici pour que les gens affichent des exemples triviaux et pourtant l'intention d'obtenir une réponse plus robuste, elles peuvent mettre à d'autres utilisations!)


Notez que 1 est de type int donc 1 << bit n'est pas sûr car il peut entraîner un débordement entier. Mieux vaut utiliser 1U .



0
votes

changeant n des bits de l'un ou l'autre côté provoque la perte de la valeur décalée pour perdre n de ce côté, de sorte que l'opération est irréversible.

Par exemple, si nous avons la valeur binaire 10101010 , et nous l'avons laissé à gauche par 4, la valeur deviendra 10100000 . Effectuer un changement de droite sur 4 ne fermez pas les bits perdus.


5 commentaires

L'OP stipule qu'il est toujours 1 << n , c'est-à-dire pas de bits élevés.


@SomeProGrammerDude, ils ne montrent qu'un exemple de 1 << n , mais disent-ils jamais que c'est le cas cessé des affaires? En effet, ils disent explicitement "1 dans mon exemple ", indiquant que l'exemple est ... Bien ... seulement un exemple, par opposition à l'étui complet / exhaustif.


Même si ce n'est pas toujours 1, vous pouvez faire répéter gauche décalageez et découvrez le nombre de décalages, même s'il y avait un débordement (mais je ne peux pas imaginer où une telle chose serait utile).


Op est ne pas demander si la valeur d'origine peut être récupérée, mais si le nombre de changements peut être déduit. À condition qu'il y ait au moins un 1 bit restant, et la valeur d'origine est connue, la réponse est "oui".


@Meathervane c'est le point. Si l'ancienne valeur n'est plus disponible, le nombre de bits décalés ne peut pas être déduit (ou au moins déduit de manière fiable).



0
votes

Vous pouvez utiliser ffs code> pour rechercher le premier jeu de bit le moins significatif:

#include <stdlib.h>
int main() {
    int bit = 4;
    int val = 1 << bit;
    // ffs counts from 1, so decrement it 
    int bit2 = ffs(val) - 1;
    printf("%d %d\n",  bit, bit2); // prints: "4 4"
}


1 commentaires

Il convient de noter que FFS est Une fonction POSIX, et donc son utilisation n'est pas portable à des systèmes non posix (comme Windows, par exemple).



0
votes

Si vous recherchez une solution C non pure C. Vous pouvez utiliser Intrinsics compilateur pour compter le nombre de zéros traînants d'un mot. Selon votre processeur, il sera implémenté avec une instruction rapide.

si __ intégré_ctzll n'est pas défini (c'est-à-dire qu'il renvoie toujours 0), vous pouvez utiliser 64 - __builtin_clzll .

vérifier avant que un seul bit soit défini. Quelque chose comme xxx

résultat: xxx


0 commentaires