Le calcul de l'étage de log_2(x) en utilisant seulement les opérateurs sur les bits en C
Pour les devoirs, à l'aide de C, je suis censé faire un programme qui trouve le logarithme de base 2 d'un nombre supérieur à 0, en utilisant seulement les opérateurs ! ~ & ^ | + << >>. Je sais que je suis censé décalage à droite d'un certain nombre de fois, mais je ne sais pas comment faire pour garder une trace du nombre de fois sans avoir toutes les boucles ou ifs. J'ai été coincé sur cette question de jours, de sorte que toute aide est très appréciée.
int ilog2(int x) {
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
}
C'est ce que j'ai jusqu'à présent. Je passe le bit le plus significatif à la fin.
Encore un de ces "bit à bit" questions qui permet
Il y a
aggregate.org/MAGIC/#Log2%20of%20an%20Integer
Le lien ci-dessus vous donnera étage(log2(x)), où x est un entier de 32 bits. Rien de trop de fantaisie à propos de la réponse mais, déplacer simplement par 1, par 2, par 4, par 8 et par 16, et en additionnant les résultats.
Puis-je obtenir des points pour que?
+
...Il y a
10
sortes de gens dans ce monde...aggregate.org/MAGIC/#Log2%20of%20an%20Integer
Le lien ci-dessus vous donnera étage(log2(x)), où x est un entier de 32 bits. Rien de trop de fantaisie à propos de la réponse mais, déplacer simplement par 1, par 2, par 4, par 8 et par 16, et en additionnant les résultats.
Puis-je obtenir des points pour que?
OriginalL'auteur Brett Cox | 2014-01-29
Vous devez vous connecter pour publier un commentaire.
Suppose un 32 bits
unsigned int
:Depuis que j'ai assumé
>
, j'ai pensé que je devais trouver un moyen de se débarrasser de lui.(u > 0xffff)
est équivalent à:((u >> 16) != 0)
. Si soustraire emprunte:((u >> 16) - 1)
va définir l'esm, le forum(u <= 0xffff)
. Remplacer-1
avec+(~0)
(permis).Donc la condition:
(u > 0xffff)
est remplacé par:(~((u >> 16) + ~0U)) >> 31
>
opérateur est un peu comme la soustraction; ne semble pas être autorisé.OriginalL'auteur Brett Hale
Votre résultat est tout simplement le rang de la plus grande non-null peu.
Une solution possible est de prendre cette méthode:
Il est basé sur l'additivité des logarithmes:
log2(2nx) = log2(x) + n
Laisser x0 être un certain nombre de 2n bits (par exemple, n=16, 32 bits).
si x0 > 2n, nous pouvons définir x1 de sorte que
x0 = 2nx1
et on peut dire que
E(log2(x0)) = n + E(log2(x1))
Nous pouvons calculer
x1
avec un décalage binaires:
x1 = x0 >> n
Sinon, on peut simplement définir X1 = X0
Nous sommes maintenant confrontés au même problème avec le reste de la moitié supérieure ou inférieure de x0
Par fractionnement de x dans la moitié à chaque étape, on peut calculer E(log2(x)):
Depuis votre sadique professeur a dit que vous ne pouvez pas utiliser de boucles, nous pouvons pirater notre façon de contourner par le calcul d'une valeur qui sera n en cas de test positif et 0 dans le cas contraire, n'a donc aucun effet sur plus ou maj:
Si le
-
opérateur est également interdite par vos troubles psychopathiques de l'enseignant (ce qui est stupide car les processeurs sont capables de gérer les 2 complète aussi bien que des opérations bit à bit), vous pouvez utiliser-x = ~x+1
dans la formule ci-dessusqui nous permettra de réduire de NIMHTNOE0WNM pour des raisons de lisibilité.
Aussi, nous allons utiliser
|
au lieu de+
puisque nous savons qu'il sera pas de report.Ici l'exemple est de 32 bits entiers, mais vous pouvez le faire fonctionner sur 64, 128, 256, 512 ou 1024 bits entiers si vous avez réussi à trouver un langage qui prend en charge un nombre entier.
Ah, mais peut-être qu'il vous était interdit d'utiliser
#define
trop?Dans ce cas, je ne peux pas faire beaucoup plus pour vous, sauf vous conseillons de le revendre à votre enseignant de la mort avec une vieille édition du K&R.
Cela conduit à inutiles, d'obfuscation de code qui dégage une forte odeur de non lavés 70 hackers.
La plupart, si pas tous les processeurs en œuvre des "compter les zéros à gauche" instructions (par exemple,
clz
sur les BRAS,bsr
sur x86 oucntlz
sur PowerPC) qui peut faire l'affaire sans tout ce tapage .Ok désolé, je n'ai pas lu la question assez attentivement. Merci pour la pluie de downvotes, BTW. Les pirates sont encore très vivante, il me semble.
OriginalL'auteur
Il obtient le plancher de logbase2 d'un nombre.
Pourquoi dites-vous cela?
Cette réponse, c'est malin, je l'aime. Je ne vois pas ce que le point de
m = 0xff | (0xff << 8);
est bien... pourquoi ne pas simplementm = 0xffff
?Désolé, l'OP a fait modifier la question pendant que j'étais à répondre, et je me demandais pourquoi ce code a été si compliqué. Habituellement, il est utilisé pour calculer le journal dans une base différente, c'est ce que je voulais dire.
OriginalL'auteur Brett Cox
La question est égal à "trouver le bit le plus élevé de 1 du nombre binaire"
ÉTAPE 1: définir la gauche de 1 tous 1
comme 0x07000000 à 0x07ffffff
ÉTAPE 2: renvoie le nombre de 1 dans word et moins 1
Référence: Le poids de Hamming
C'est comment je le fais. Merci~
OriginalL'auteur mi al
Vous êtes autorisé à l'utiliser
&
alors pouvez-vous utiliser&&
? Avec que vous pouvez le faire à des conditions sans avoir besoin deif
peut être fait avec
Sinon, si vous voulez attribuer une valeur conditionnelle comme
value = cond ? a : b;
alors vous pouvez le faire avec&
D'une autre façon:
ou
une autre façon
http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
OriginalL'auteur phuclv
J'ai aussi été affecté à ce problème pour les devoirs et j'ai passé une quantité importante de temps à réfléchir à ce sujet donc je pensais que je voudrais partager ce que je suis venu avec. Cela fonctionne avec des entiers sur un ordinateur 32 bits. !!x retourne si x est zéro ou un.
OriginalL'auteur swsmith