Pourquoi ce code pour plus(à l'aide d'opération au niveau du bit) fonctionne en java
public int add(int a, int b){
while (b != 0){
int carry = (a & b) ;
a = a ^ b;
b = carry << 1;
}
return a;
}
C'est le code pour calculer la somme de deux nombres entiers à l'aide opération au niveau du bit.
Si je fais le calcul manuellement ou par programmation, je vois qu'il fonctionne pour tout entier.
Mais je ne suis pas en mesure de comprendre la relation entre la valeur intermédiaire de l' a
et carry
.
et pourquoi est multiplié par 2 pour attribuer à b
?
PS: j'ai trouvé la réponse ici
Au niveau du bit de Multiplier et de les Ajouter en Java
mais c'est pour la multiplication et pas pour l'addition.
Avez-vous des connaissances sur la bit-wise plus?
Le porter de un chiffre est ajouté à la chiffres, bien sûr. Cet algorithme ne fait "plus comme vous le savez de l'école", mais de mélanger un peu au lieu de soin digit par digit - il fait une addition sans porte en premier (xor), puis ajoute la carie séparément (encore une fois de la même manière) jusqu'à ce qu'il n'y a pas plus de porte (donc il ajoute le porte-généré par l'ajout de-porte, puis la porte généré par le plus et ainsi de suite). Ce doit résilier car ne porte que des aller "à gauche" - si au moins un bit est "fixe" après chaque itération.
oui, j'ai, qu'est-ce que votre point de toute façon?
merci beaucoup..en fait j'ai été trouver qu'il est difficile de croire comment réaliser au cours des prochaines bits fonctionne en binaire car il n'est pas le cas, bit par bit de départ..
je voulais vous expliquer comment cela fonctionne et je voulais savoir sur quel niveau vous êtes. Donc, il aurait été plus facile pour moi d'expliquer (et de ne pas écrire des trucs que vous connaissez déjà).
Le porter de un chiffre est ajouté à la chiffres, bien sûr. Cet algorithme ne fait "plus comme vous le savez de l'école", mais de mélanger un peu au lieu de soin digit par digit - il fait une addition sans porte en premier (xor), puis ajoute la carie séparément (encore une fois de la même manière) jusqu'à ce qu'il n'y a pas plus de porte (donc il ajoute le porte-généré par l'ajout de-porte, puis la porte généré par le plus et ainsi de suite). Ce doit résilier car ne porte que des aller "à gauche" - si au moins un bit est "fixe" après chaque itération.
oui, j'ai, qu'est-ce que votre point de toute façon?
merci beaucoup..en fait j'ai été trouver qu'il est difficile de croire comment réaliser au cours des prochaines bits fonctionne en binaire car il n'est pas le cas, bit par bit de départ..
je voulais vous expliquer comment cela fonctionne et je voulais savoir sur quel niveau vous êtes. Donc, il aurait été plus facile pour moi d'expliquer (et de ne pas écrire des trucs que vous connaissez déjà).
OriginalL'auteur Sunny | 2013-06-27
Vous devez vous connecter pour publier un commentaire.
Rappelons tout d'abord plus à l'école primaire. par exemple, 26 + 147 = 173. Vous commencez par 6+7=13, donc on doit en mettre 3 dans la somme, et de réaliser l'un, et ainsi de suite - qui est: vous ajoutez les deux chiffres et de porter un si nécessaire.
Le code fait à peu près la même chose sur des nombres binaires, mais avec un petit tweak. Au lieu de prendre un chiffre position à un moment, il prend toutes un seul coup. Au lieu de le transporter à partir de la position i-1 à i (c'est à dire y compris 1 lors de l'ajout de 2 et 4), le code d'ajouter toutes les caries dans un deuxième itération. Donc, ce qu'il n'est:
026+147 = 163 + 010 = 173 + 000
Pour les nombres binaires a=6=00110 et b=7=00111 vous obtenez
D'abord vous trouver la porte; c'est-à toutes les positions où les deux
a
etb
a son bit set:int carry = (a & b) ;
Alors l'id de l'ajout de chiffres, en ignorant le porter, et les stocke dans
a
:a = a ^ b;
Cela permettra de répondre à6+7=3
dans l'exemple.La dernière partie de quarts de l'procéder à la prochaine chiffres position, c'est à dire assurer la 1-effectuer dans l'exemple est "déplacé" de la 1 à la 10:
carry << 1;
La boucle while continue aussi longtemps que il ya de porte qui n'a pas été inclus dans la somme.
si vous ajoutez 1 à 0xFFFFFFFF (aka -1), il interviendra tout le chemin à travers bits par bits en 32 étapes (ou un nombre suffisamment près de 32, je fais souvent des tout-en-un d'erreurs)
oh merci..l'image est très clair dans mon esprit maintenant..je peux me déplacer pour des pièces complexes avec satisfaction..:)
Comment est 7 en binaire = 00101? Il ne faut pas être 00111
Good job!!! Vous avez raison. Merci 🙂 mise à Jour de la réponse.
OriginalL'auteur Tobber
Les variables
b
etcarry
sont utilisés pour "transporter" des chiffres supplémentaires. Par exemple, dans le système binaire,1+1 = 10
, mais10
est un nombre à deux chiffres. Le1
dans10
doit être placé dans le prochain chiffre à la gauche. C'est ce que l'while()
boucle dans votre programme. Partout où il y a1
chiffres dans le même endroit (a & b
),carry
est défini pour le XOR deb
(a ^ b
). cela donne à chaque chiffre de la valeur de1
seulement sia
oub
, mais pas les deux, a la valeur 2. (Quand on fait de l'arithmétique binaire, c'est exactement ce qui se passe;1+1 = 10
, donc depuis deux1
s sont ajoutés ensemble, ceux que l'endroit est0
). Après cela,carry << 1
(carry*2
oucarry
décalé à gauche par un) est attribué àb
. La boucle se répète alors, en utilisant les nouvelles valeurs dea
etb
jusqu'àb
est de zéro (ce qui signifiecarry
est aussi égal à zéro).OriginalL'auteur IanPudney
Certainement penser à tous les numéros dans ici en système binaire.
Ce que Vous l'habitude de trouver dans ce type de code est un "invariant de boucle". Dans ce cas, Vous aimeriez voir que a + b est constante après chaque itération. Ainsi, si b devient 0 et nous sortir de la boucle, doit être égale à la somme de l'original de a et b. La prochaine étape est de s'assurer que la boucle terminera finalement. Nous y reviendrons plus tard, d'abord essayons de comprendre l'invariant partie, qui dans ce cas est d'utiliser l'égalité:
où dans la boucle de nouvelles sera égal à la vieille a ^ b et de nouveaux b sera de 2 * (a & b), qui est la même chose que (a & b) << 1. C'est l'essence de Votre problème de trouver cette égalité. C'est exactement la façon dont Vous faites le plus.
Je vais vous présenter deux solutions.
Dans les deux, je vais utiliser un simple fait que:
Chaque fois que x et y n'ont aucune commune bits.
Le court chemin pour voir ce officiellement est à noter que:
Le long de la solution utilise l'induction mathématique comme suit (cela peut être considéré comme excessif par certains, mais dans mon option, il vaut la peine de le savoir):
D'abord assurez-vous qu'il fonctionne avec a et b les deux égales à zéro (Vous pouvez aussi le faire pour un peu de chiffres qui expliquent beaucoup de comment cet algorithme fonctionne). N'oubliez pas cette étape lors de l'utilisation d'induction mathématique.
Ensuite, supposons cela fonctionne pour les n-1 bits des nombres, nous nous devons de montrer que ça marche pour n bits. Maintenant écrire a = 2a' + a" = 2a' ^ a" et b = 2b' + b" = 2b' ^ b" au cas où", b" sont dans l'ensemble {0, 1} (alors 2a "et" n'ont pas de commune bits!).
Alors:
Maintenant, la dernière chose à vérifier est que cette boucle de vraiment se termine.
pour voir cela utiliser le fait que, à chaque étape à la fois a et b sont non-négatives, et que cela reste vrai après chaque itération.
Par conséquent, nous avons obtenu que b <= a + b.
Prochaine note qu'après n étapes b a finir de n zéros. On ne peut donc pas faire plus que log_2(a+b) mesures depuis, nous aurions soit b = 0 ou b = k * 2*n >= 2*n > 2**log_2(a+b) = a+b contredire l'hypothèse.
Ici ** indique l'exponentiation de cours.
En Java cet algorithme serait également travailler sur les nombres entiers négatifs. C'est parce que de la façon dont les entiers négatifs sont stockés en Java et dans la plupart des langages de programmation
Ici, l'addition et la soustraction des entiers signés et non signés numéros fonctionne de manière identique sur les bits, donc le code qui fonctionne pour les numéros de travail pour la signature.
OriginalL'auteur catvir
Il s'appuie sur le fait que 1+1=10 (bit à bit), c'est à dire "si un ajout implique un bit de retenue, puis la somme du courant de chiffres de la colonne doit être de zéro". Penser à la "<<" opérateur "porter les bits vers la gauche" au lieu de penser "multiplier un entier par 2"
Voici un prosaïque description du code.
OriginalL'auteur bonger22
Oui, comme beaucoup de réponses ici, il fonctionne comme rudimentaire de l'école de mathématiques pour ajouter deux nombres. Mais en Binaire.
Beaucoup mieux à comprendre avec des exemples, des petits exemples.
OriginalL'auteur sivag1