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));
^
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.