web-dev-qa-db-fra.com

Qu'est-ce qu'un ^ b et (a & b) << 1?

Je faisais ça question dans leetcode.

Demande:

Calculez la somme de deux entiers a et b, mais vous n'êtes pas autorisé à utiliser l'opérateur + et -.

Je ne comprends pas la solution qu'elle a donnée

Quelqu'un pourrait-il expliquer le fonctionnement de cette fonction getSum?

Voici la réponse dans JS:

var getSum=function(a,b) {
    const Sum = a^b; //I can't understand how those two line's code can
    const carry = (a & b) << 1; //get the sum
        if(!carry) {
            return Sum
        }
    return getSum(Sum,carry);
};
console.log(getSum(5,1));
26
Jacky

^ Est XOR, une opération au niveau du bit. Sur un seul bit, les règles sont 0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 0 Et 1 ^ 1 = 0, Et vous étendez simplement l'exécuter sur les bits correspondants lorsque vous traitez avec plusieurs -bit values. Le nom est l'abréviation de "exclusif ou" et vient du fait que A ^ B Est 1 Si et seulement si A ou B est 1, Pas les deux. Mais, il est plus intéressant de parler de son autre nom, ⊕. ⊕ est + mais légèrement différent. Vous remarquerez que les règles pour ⊕ sont similaires aux règles d'ajout: 0 + 0 = 0, 0 + 1 = 1, 1 + 0 = 1 Et 1 + 1 = 10. ⊕ est +, sauf 1 ⊕ 1 = 0; c'est-à-dire, ⊕ est +, sauf sans porter. Cela vaut pour plusieurs bits: 011 + 001 = 100, Parce que vous portez un 1 De celui qui est placé à la place deux, puis que vous portez à nouveau un 1 À la place quatre. Ensuite, 011 ⊕ 001 = 010, Parce que vous ne portez tout simplement pas.

Maintenant, quand vous faites un véritable ajout, quand portez-vous? En binaire, la réponse est très simple: vous portez un 1 À l'endroit suivant quand il y a deux 1 S à un endroit donné. Ceci est facilement compris comme un ET au niveau du bit, &. 1 & 1 = 1 Et 0 Sinon. Pour 011 + 001, L'ajout sans portage donne 011 ⊕ 001 = 010, Et nous pouvons dire que nous devons transporter un 1 Hors de leur emplacement parce que 011 & 001 = 001. Le déplacement de (a & b) << 1 Transforme un nombre "d'où dois-je transporter?" dans "où dois-je ajouter des portages?": (011 & 001) << 1 = 010; J'ai besoin d'ajouter un peu de transport à la place de deux.

Donc, dans getSum, nous voulons connaître a + b. Nous calculons l'addition sans transporter avec a ^ b, Et nous trouvons où nous devons ajouter des bits de transport avec (a & b) << 1. Maintenant, nous avons juste besoin d'ajouter ces deux ensemble. Eh bien, nous avons déjà une fonction pour additionner des nombres; il s'appelle getSum. Donc, nous écrivons simplement function getSum(a, b) { return getSum(a ^ b, (a & b) << 1); }, sauf que nous nous assurons de court-circuiter s'il n'y a rien à transporter, ce qui nous évite une récursion infinie.

0
HTNW