Pourquoi préférer en complément à deux sur le signe et l'ampleur de nombres signés?
Je suis juste curieux de savoir si il y a une raison pour laquelle, dans le but de représenter -1 binaire en complément à deux est utilisé: en feuilletant les bits et en ajoutant 1?
-1 est représenté par 11111111 (complément à deux) plutôt que (pour moi plus intuitive) 10000001 qui est binaire 1 avec le premier bit comme négatif drapeau.
Avertissement: je n'ai pas compter sur l'arithmétique binaire pour mon travail!
- ITT — hivemind.
- FWIW, votre "intuition" méthode d'utilisation d'un signe-bit est occasionnellement utilisé, par exemple, la plupart des ordinateurs utilisent un signe bits pour représenter des nombres à virgule flottante.
- Il est appelé signé ampleur
- J'ai toujours associé le signe et l'ampleur de la représentation avec des entiers depuis des nombres à virgule Flottante contiennent trois composants: un signe, un exposant, et une mantisse (souvent avec un implicite '1'). Mais je suppose que c'est assez facile à traiter l'exposant et la mantisse que la grandeur tant que l'on se rend compte qu'ils ne sont pas strictement linéaire.
- Voici un article discuter de la façon dont les nombres à virgule flottante sont stockés en binaire, pour ceux qui sont curieux à propos de @Adisak remarques.
- Viens de voir une belle vidéo expliquant ce youtube.com/watch?v=dHB7jFjESLY
Vous devez vous connecter pour publier un commentaire.
Il est fait de sorte que plus n'a pas besoin d'avoir de la logique pour traiter les nombres négatifs. Découvrez l'article sur Wikipedia.
Dire que vous avez deux numéros, 2 et -1. Dans votre "intuition" manière de représenter les nombres, ils seraient
0010
et1001
, respectivement (je suis coller à 4 bits pour la taille). En complément à deux, elles sont0010
et1111
. Maintenant, disons que je veux ajouter.En complément à deux outre est très simple. Vous ajoutez des numéros normalement et aucun bit de retenue à la fin est supprimée. Ils sont donc ajouté comme suit:
0001
est 1, qui est le résultat attendu de "2+(-1)".Mais dans votre "intuitive" de la méthode, l'ajout est plus compliqué:
Qui est -3, droit? Plus Simple ne fonctionne pas dans ce cas. Vous avez besoin de noter que l'un des nombres est négatif et l'utilisation d'un algorithme différent si c'est le cas.
Pour cette "intuitive" méthode de stockage, la soustraction est une opération de plus, l'exigence des contrôles supplémentaires sur les numéros avant qu'ils puissent être ajoutés. Puisque vous voulez la plupart des opérations de base (addition, soustraction, etc) pour être aussi rapide que possible, vous avez besoin de stocker des nombres dans une manière qui vous permet d'utiliser le plus simple des algorithmes possible.
En outre, dans le "intuitive" méthode de stockage, il y a deux zéros:
Qui sont intuitivement le même numéro, mais avoir deux valeurs différentes lorsqu'elles sont stockées. Chaque application devra prendre des mesures supplémentaires pour s'assurer que les valeurs non nulles sont pas aussi négatif zéro.
Il y a un autre bonus avec le stockage des entiers de cette façon, et c'est quand vous avez besoin d'étendre la largeur de ce registre, la valeur est stockée dans. Avec en complément à deux, le stockage d'un 4-nombre de bits dans un 8-bit registre est une question de répéter son bit de poids fort:
C'est juste une question de regarder le bit de signe de la plus petite parole et le répéter jusqu'à ce qu'elle augmente la largeur du plus grand mot.
Avec votre méthode, vous devrez effacer le mot de bits, qui est un supplément de fonctionnement en plus de rembourrage:
Vous devez encore définir les 4 bits dans les deux cas, mais dans le "intuitive" cas, vous devez effacer la 5ème peu aussi. C'est une petite étape supplémentaire dans l'une des plus fondamentales et les opérations les plus courantes présentes dans chaque application.
how we arrived at 2s compliment the first place.
cs.cornell.edu/~tomf/notes/cps104/twoscomp.html1111
être négatif . Il ne fonctionne pas quand j'essaie de le convertir en décimal. Je suis si confus?1111
MSB est1
si nombre est négatif alors comment la partie restante indique qu'il est en-1
. Je veux dire qu'il ne pas ajouter à l'1
de sorte que le résultat devient-1
.MSB dire que le nombre est négatif. Ce Qui Se Passe Vraiment?1
indique-8
, et les trois autres1
s indiquent4
,2
, et1
, respectivement, de sorte-8+4+2+1 = -1
.int x = -4
, et je puis faireprintf("%d" , x)
comment est-il interprété ? Aussi quelle est la différence entreunsigned int
etsigned int
et%d
et%u
... ce qui a été m'énerve pour un long moment maintenant .Merci.%d
les forces de l'imprimer comme un entier signé, et%u
forcé à imprimer comme un entier non signé.signed int a = -1
, puis-1
en 2 forme de complément est11111111 11111111 11111111 11111111
et puis quand j'utilise%d
de l'interpréter, il imprime-1
et%u
, il imprime4294967295
et quand j'écrissigned int a = 2
, il imprime2
lorsque j'utilise%d
et aussi lorsque j'utilise%u
. Si 2 serait en complément à deux, il serait11111111 11111111 11111111 11111101
, et puis ce serait une très diffrenet réponse , ce que je veux poser est: quand est-complément de 2 arriver est qu'il dépend de-
signe ou il arrive pour tout entier si le type est signé int qui ne doit pas être le cas ici.unsigned int a = -1
, puis-1
en 2 forme de complément est11111111 11111111 11111111 11111111
et puis quand j'utilise%d
de l'interpréter, il imprime-1
et%u
, il imprime4294967295
.Donc, si un nombre est négatif, il est alwasys stockées en tant que complément de 2 peu importe le type non signé ou signé , c'est bien cela ... cette question a été mise sur écoute de moi pendant un moment , j'aurais demandé une nouvelle question sur stackoverflow , mais mon expérience me dit qu'il n'est pas très sympathique pour les débutants , donc je suis peur d'écrire une nouvelle question.signed char x = -1
etunsigned char y = -1
ont la même représentation en mémoire. Les uns et de zéros dans le même ordre. La seule différence entre les deux est de savoir comment ils sont interprétés. Lorsqu'il est stocké dans un unsigned variable, ils sont interprétés comme non signés. Lorsqu'il est stocké dans signé variables, ils sont signés. Lors de l'impression signé, ils sont signés, etc. Le même est vrai pourun/signed char z = 2
.Wikipédia dit tout:
En d'autres termes, l'ajout est le même, si le nombre est négatif.
Même si cette question est ancienne , permettez-moi de mettre dans mes 2 cents.
Avant je expliquer cela ,revenons à l'essentiel. 2' complément est de 1 effectif + 1 .
Maintenant quel est le 1er complément et quelle est sa signification en outre.
Somme de n bits et son 1er complément vous donne le plus grand nombre qui peut être représenté par ces n bits.
Exemple:
Maintenant ce qui va se passer si nous essayons d'ajouter 1 au résultat. Il se traduit par un dépassement de capacité.
Le résultat sera
1 0000
qui est 0 ( car nous travaillons avec de bit 4 numéros (1 à gauche, c'est un débordement )Donc ,
Quelqu'un a alors décidé d'appeler 1 effectif + 1 2'complement. Si la déclaration ci-dessus devient:
Tout n'bit numéro + son complément de 2 = 0
ce qui signifie 2 en complément d'un nombre = - (de ce nombre)
Tout cela aboutit à une question , pourquoi ne pouvons-nous utiliser uniquement le (n-1) de n bits pour représenter un nombre positif, et pourquoi le plus à gauche de la n-ième bit de représenter le signe (0 sur la gauche en bits +ve nombre , et 1 signifie -ve numéro ) . par exemple pourquoi nous utilisons uniquement les 31 premiers bits d'un int en java pour représenter le nombre positif si la 32e bit est à 1 , de ses nombre de cinq.
1 0000 (le résultat est égal à zéro , avec le report 1 de débordement)
Ainsi, le système de (n + 2'complement de n) = 0 , fonctionne toujours. La seule ambiguïté est ici complément de 2 de 12 0100 d'une manière ambiguë, qui représente également +8 , autre que le représentant -12 en 2s, le système du complément.
Ce problème sera résolu, si les nombres positifs ont toujours un 0 à gauche de la plupart des bits. Dans ce cas, leur complément de 2 permettra de toujours avoir un 1 dans leurs plus à gauche , et nous n'aurez pas l'ambiguïté de la même série de bits représentant un complément de 2, le numéro un +ve nombre.
En complément à deux permet d'addition et de soustraction à faire dans la voie normale (comme vous plaie pour les nombres non signés). Il empêche également -0 (un moyen de représenter de 0 qui ne serait pas égal à 0 avec la normale de bit-par-bit méthode de comparaison des nombres).
c'est pour simplifier des sommes et des différences de nombres. une somme d'un nombre négatif et un positif, codifiée par 2 complète est la même qu'en faisant la somme normalement.
L'habitude de la mise en œuvre de l'opération est "inverser les bits et 1", mais il y a une autre manière de définir ce qui constitue probablement la justification claire. Complément de 2 est la forme que vous obtenez si vous prenez l'habitude unsigned représentation où chaque bit contrôle de la puissance de 2, et il suffit de faire le plus significatif terme négatif.
En prenant une valeur de 8 bits7 a6 a5 a4 a3 a2 a1 a0
L'habitude binaire non signé interprétation est:
27*7 + 26*6 + 25*5 + 24*4 + 23*3 + 22*2 + 21*1 + 20*0
11111111 = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255
Le complément à deux est de l'interprétation:
-27*7 + 26*6 + 25*5 + 24*4 + 23*3 + 22*2 + 21*1 + 20*0
11111111 = -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = -1
Aucun des autres bits du changement de sens du tout, et porter un7 est "dépassement" et ne devrait pas travailler, donc à peu près toutes les opérations arithmétiques de travail sans modification (comme d'autres l'ont noté). Signe-amplitude généralement inspecter le bit de signe et de l'utilisation d'une logique différente.
En complément à deux permet positifs et négatifs des nombres à additionner, sans logique.
Si vous avez essayé d'ajouter 1 et -1 à l'aide de votre méthode
10000001 (-1)
+00000001 (1)
vous obtenez
10000010 (-2)
Au lieu de cela, en utilisant en complément à deux, nous pouvons ajouter
11111111 (-1)
+00000001 (1)
vous obtenez
00000000 (0)
La même chose est vraie pour la soustraction.
Aussi, si vous essayez de soustraire 4 de 6 (deux nombres positifs), vous pouvez complément de 2 4 et ajouter les deux ensemble 6 + (-4) = 6 - 4 = 2
Cela signifie que la soustraction et l'addition de deux nombres positifs et négatifs peut être fait par le même circuit dans le cpu.
De s'étendre sur les autres réponses:
En complément à deux
Division a besoin d'un mécanisme différent.
Tous ces vrai parce qu'en complément à deux est tout à fait normale, l'arithmétique modulaire, où nous choisir de regarder quelques chiffres négatifs en soustrayant le modulo.
unsigned mul(unsigned short x, unsigned short y) { return x*y; }
[16-bits court; 32-bit int] va parfois générer du code qui ne fonctionnera pas correctement si le produit est supérieure à 2147483647.De lire les réponses à cette question, je suis tombé sur ce commentaire [édité].
À mon avis, la question posée dans ce commentaire est très intéressant et je voudrais donc tout d'abord à la reformuler, puis de fournir une réponse et un exemple.
QUESTION – Comment le système peut-il établir une ou plusieurs octets adjacents doivent-ils être interprétés? En particulier, comment le système peut-il déterminer si une séquence d'octets est un simple nombre binaire ou un complément de 2 nombre?
RÉPONSE – Le système établit la façon d'interpréter une séquence d'octets par types.
Types de définir
EXEMPLE ci-Dessous, nous supposons que
char
s'sont de 1 octet de longshort
's sont les 2 octetsint
's etfloat
s'sont de 4 octets de longVeuillez noter que ces tailles sont spécifiques à mon système. Bien qu'assez commun, ils peuvent être différents d'un système à l'autre. Si vous êtes curieux de ce qu'ils sont sur votre système, utilisez la opérateur sizeof.
Tout d'abord, nous définissons un tableau contenant 4 octets et initialiser tous pour le nombre binaire
10111101
, correspondant au nombre hexadécimalBD
.Puis nous avons lu de la matrice de contenu à l'aide de différents types.
unsigned char
etsigned char
unsigned short
etshort
unsigned int
,int
etfloat
Les 4 octets dans la mémoire vive (
l_Just4Bytes[ 0..3 ]
) restent toujours exactement la même. La seule chose qui change, c'est la façon dont nous les interprétons.De nouveau, nous dire le système de comment de les interpréter à travers types.
Par exemple, ci-dessus, nous avons utilisé les types suivants d'interpréter le contenu de la
l_Just4Bytes
tableauunsigned char
: 1 octet dans la plaine binairesigned char
: 1 octet en complément de 2unsigned short
: 2 octets dans la plaine de la notation binaireshort
: 2 octets en complément de 2unsigned int
: 4 octets dans la plaine de la notation binaireint
: 4 octets en complément de 2float
: 4 octets dans la norme IEEE 754 simple précision de la notation[EDIT] Ce message a été modifié après le commentaire par user4581301. Merci d'avoir pris le temps de laisser tomber ces quelques lignes!
int x = -4
, et je puis faireprintf("%d" , x)
comment est-il interprété ? Aussi quelle est la différence entreunsigned int
etsigned int
et%d
et%u
... ce qui a été m'énerve pour un long moment maintenant .Merci.int
types, lesigned
modificateur est par défaut. Cela signifie queint
etsigned int
sont exactement du même type. Ainsi, les deux définitionsint i = -4;
etsigned int i = -4;
ont le même sens.int
est de 4 octets complément de 2 et ununsigned int
est de 4 octets plaine binaire la notation (vérifiez le type réel de la taille de votre système à l'aide de lasizeof
opérateur).int x = -4;
vous en avez la suite adjacente 4 octets quelque part dans la mémoire RAM:11111111 11111111 11111111 11111100
; tandis que, aprèsunsigned int x = 4;
le 4 adjacentes octets de RAM serait00000000 00000000 00000000 00000100
.printf
mise en forme, vous pouvez utiliser à la fois%d
et%u
avec unint
ou ununsigned int
. En fait, si vous utilisez%d
"Laint
argument est converti en décimal signé dans le style [−]dddd" et un analogue de la conversion à l'aide de%u
.d
etu
sont appelés "conversion des spécificateurs" dans le C Standard.Vous pouvez regarder le Professeur Jerry Caïn de l'université Stanford, en expliquant le complément à deux, la deuxième conférence (l'explication concernant le complément de 2 démarre autour de 13:00) dans la série de conférences appelé Paradigmes de Programmation disponibles pour regarder de Standford la chaîne YouTube de. Voici le lien vers la conférence de la série: http://www.youtube.com/view_play_list?p=9D558D49CA734A02.
En complément à deux est utilisé car il est plus simple à mettre en œuvre dans les circuits et ne permet pas aussi négatif zéro.
Si il y a x bits en complément à deux vont de +(2^x/2+1)- (2^x/2). Un complément sera exécuté à partir d' +(2^x/2)- (2^x/2), mais il sera permis à un négatif zéro (0000 est égal à 1000 en 4 bit 1 du système du complément).
Bien, votre intention n'est pas vraiment à inverser tous les bits de votre nombre binaire. Il est en fait de soustraire chacun des chiffres de 1. C'est juste une coïncidence heureuse que soustrayant 1 de 1 en 0 et en soustrayant 0 de 1 à 1. Donc, le retournement des bits est la réalisation de cette soustraction.
Mais pourquoi êtes-vous trouver chaque chiffre de la différence à partir de 1? Eh bien, vous n'êtes pas. Votre objectif réel est de calculer le nombre binaire de la différence à partir d'un autre nombre binaire qui a le même nombre de chiffres, mais qui ne contient que des 1. Par exemple, si votre numéro est 10110001, lorsque vous retournez tous ces éléments, vous êtes effectivement l'informatique (11111111 - 10110001).
C'est ce qui explique la première étape dans le calcul du Complément à Deux. Maintenant, nous allons inclure la deuxième étape: ajouter 1 -- aussi dans l'image.
Ajouter 1 au-dessus binaire équation:
11111111 - 10110001 + 1
Qu'obtenez-vous? Ce:
100000000 - 10110001
C'est l'équation finale. Et par la réalisation de ces deux étapes, vous essayez de trouver cette, dernière différence: le nombre binaire soustraite à partir d'un autre nombre binaire avec un chiffre supplémentaire et contenant des zéros, sauf à le plus de signification position de bit.
Mais pourquoi sommes-nous hankerin " après cette différence vraiment? Ainsi, à partir de là, je suppose que ce serait mieux si vous lisez le Article de Wikipedia.
Nous seulement effectuer des opération d'addition pour à la fois l'addition et la soustraction. Nous ajoutons le second opérande de la première opérande pour l'addition. Pour la soustraction, nous ajoutons les 2 en complément de la deuxième opérande à la première opérande.
Avec un complément de 2 représentation nous n'avons pas besoin de séparer les composants numériques pour la soustraction uniquement les additionneurs et complementers sont utilisés.
Il est intéressant de noter que sur certaines des premières machines à calculer, avant l'avènement des ordinateurs numériques, de la soustraction sera effectué par l'opérateur d'entrer des valeurs à l'aide de différentes couleurs ensemble de légendes sur chaque touche (de sorte que chaque clé entrez neuf moins le nombre à soustraire), et appuyez sur un bouton spécial allait assumer un report dans un calcul. Ainsi, sur un à six chiffres de la machine, de se soustraire 1234 à partir d'une valeur, l'opérateur de frapper les touches qui serait normalement indiquer "998,765" et appuyer sur un bouton pour ajouter cette valeur, plus un pour le calcul en cours. En complément à deux arithmétique est tout simplement l'équivalent binaire de cette "dix-complément" de l'arithmétique.
L'avantage d'effectuer la soustraction par le complément de la méthode est la réduction du matériel
la complexité.Il n'existe aucun besoin de les différents circuit numérique pour l'addition et la soustraction.les deux
l'addition et la soustraction sont réalisées par l'additionneur seulement.
Un avantage majeur de complément à deux de la représentation qui n'a pas encore été mentionné ici, c'est que les bits de poids faible d'un complément à deux, somme, différence, produit ou dépendantes seulement sur les bits correspondants des opérandes. La raison que les 8 bits signé valeur -1 est
11111111
est que soustrayant tout entier dont plus bas de 8 bits sont00000001
partir de n'importe quel autre nombre entier, dont les plus bas de 8 bits sont0000000
donnera un entier dont la plus basse de 8 bits sont11111111
. Mathématiquement, la valeur -1 serait une infinie chaîne de 1, mais toutes les valeurs à l'intérieur de la portée d'un particulier de type entier sera tous les 1 ou 0 delà d'un certain point, donc c'est pratique pour les ordinateurs de "signe-les étendre" le bit le plus significatif d'un certain nombre, comme si elle représentait un nombre infini de 1 ou de 0.En complément à deux est à peu près le seul signés-nombre de représentation qui fonctionne bien lorsque vous traitez avec des types plus grande qu'une machine binaire naturel de la taille de mot, puisque lors de l'exécution de l'addition ou de la soustraction, de code permet de récupérer le plus bas morceau de chaque opérande, calcul de la plus faible part de ce résultat, et en magasin, puis de charger le segment suivant de chaque opérande, calculer la partie suivante du résultat, et de magasin, etc. Ainsi, même un processeur qui exige que toutes les additions et les soustractions de passer par un seul de 8 bits registre peut gérer 32 bits des nombres signés de façon raisonnablement efficace (plus lent qu'avec une version 32 bits de registre, bien sûr, mais encore utilisable).
Lors de l'utilisation de tout autre signé représentations autorisées par la Norme, tous les bits de la suite susceptible d'être touché par n'importe quel bits des opérandes, ce qui rend nécessaire de détenir un ensemble de valeur dans les registres à la fois, ou bien de suivre les calculs avec une étape supplémentaire qui, dans certains cas au moins, exiger de la lecture, de modification et de réécriture de chaque morceau de la suite.
printf
sera sortie de -4. Sane implémentations sur la banalité du matériel permettra de traiter les valeurs signées deINT_MIN
à -1 comme équivalent à des valeurs non signées deINT_MAX+1u
àUINT_MAX
, mais la Norme serait de permettre à un compilateur de faire tout ce qu'il aime si%u
ou%x
est utilisé sur une valeur de typeint
ou "%i " ou%d
est utilisé sur une valeur de typeunsigned
.signed int a = -1
, puis ` -1` dans 2 forme de complément est11111111 11111111 11111111 11111111
et puis quand j'utilise%d
de l'interpréter, il imprime -1 et %u , il imprime4294967295
et quand j'écrissigned int a = 2
, il imprime en 2 quand j'utilise%d
et aussi lorsque j'utilise%u
. Si2
serait en complément à deux, il serait11111111 11111111 11111111 11111101
, et puis ce serait une très diffr réponse , ce que je veux poser est: quand est-complément de 2 arriver est qu'il dépend de signer ou il arrive pour tout entier si le type estsigned int
qui ne doit pas être le cas ici.Une réponse satisfaisante pourquoi les Deux2 Complément qui est utilisé pour représenter les nombres négatifs plutôt que le système du Complément est que
En Complément à deux système résout le problème de de multiples représentations de l'0 et de la nécessité pour fin autour de transporter qui existent dans le complément du système de représentation des nombres négatifs.
Pour plus d'informations, Visitez https://en.wikipedia.org/wiki/Signed_number_representations
Pour la Fin de autour de transporter Visite
https://en.wikipedia.org/wiki/End-around_carry
parce que les fabricants de processeurs sont paresseux!