7
votes

Définir le bit x d'un entier à bit y d'un autre entier sans ramification?

La fonction copy_bit ci-dessous est simplifiée en quelque chose comme out [OUT_BIT] = dans [in_bit] ? (c.-à-d. ne pas utiliser de si instruction) xxx

update: juste pour être clair, ce n'est pas des devoirs ou un problème xy où suggérant std :: bitset répond à la question.


5 commentaires

Eh bien, nous ne nous soucions pas de devoirs. Nous devrions simplement résoudre le problème pour de vraies applications.


@Reeegavirel Vous avez raison, mais je voulais dire cette partie avec out [Out_bit] = dans [in_bit] . Est-il possible de le faire directement?


@ALIREZA: OUT [OUT_BIT] = Dans [in_bit] n'implique pas que les bits doivent être modifiés directement, car en C ++, vous pouvez surcharger opérateur [] .


Non mentionné n'importe où encore, mais un comportement non défini est causé par 1 << in_bit si in_bit> = char_bit * Taille de (int) quel que soit t ; Pensez à faire static_cast (1) , et si t peut être signé puis de jeter à la version non signée de t


+1 pour mentionner le problème xy :)


3 Réponses :


9
votes

Vous pouvez le faire comme ça comme ceci comme suit:

//Change the bit if and only if they are not equal:
out ^= (((out >> out_bit) ^ (in >> in_bit)) & 1) << out_bit;


3 commentaires

Points bonus Si vous pouvez profiler cela et comparer avec le code d'origine (il est difficile de voir pourquoi OP apporte cette demande à moins qu'il ne pense qu'il peut surpasser son compilateur pour des gains de performance)


J'ai fait la partie difficile, laissez quelqu'un d'autre faire le profilage (:. de toute façon que la demande était de simplifier le code de ne pas l'optimiser.


Je ne suis pas sûr que beaucoup de gens considèrent que cela plus "simple" que le code d'origine :)



4
votes

Essayez ceci: xxx

explication:

  • (out & ~ (1 << OUT_BIT)) Laissez les bits de out qui ne sont pas intéressants.
  • (dans & (1 << in_bit) Sélectionnez le bit de dans qui est intéressant
  • (((dans & (1 << in_bit)) >> in_bit) << OUT_BIT) Positionnez le bit dans la bonne position.

1 commentaires

Bonne explication, mais ((((dans & (1 << in_bit)) >> in_bit) << OUT_BIT) pourrait être simplifié à (((((dans >> in_bit) et 1) < , enregistre un quart de travail.



6
votes

Un moyen de le faire dans une ligne serait de réinitialiser d'abord le bit de sortie à zéro, puis ou avec n'importe quel bit le numéro dans est: xxx < / p>


3 commentaires

Trop d'opérateurs d'affectation composés; Il est très difficile de prouver que cela a un comportement indéfini.


Oui, je suis moi-même confondu avec des points de séquence. Je crois que ma réponse pourrait effectivement avoir un comportement indéfini.


en C ++ 03, il a sûrement un comportement non défini (deux missions à la même variable sans point de séquence intermédiaire), bien que cela soit facilement fixé en n'utilisant pas l'affectation du composé