J'ai entendu C, C++, Java utilise deux compléments pour la représentation binaire. Pourquoi ne pas utiliser 1 complément? Y a-t-il un avantage à utiliser 2 complément plus qu'un complément?pourquoi C, C++, Java n'utilise pas un complément?
Répondre
Travailler avec des entiers signés complémentaires à deux est beaucoup plus propre. Vous pouvez essentiellement ajouter des valeurs signées comme si elles n'étaient pas signées et faire en sorte que les choses fonctionnent comme prévu, plutôt que d'avoir à traiter explicitement une addition supplémentaire. Il est également plus facile de vérifier si une valeur est 0, car le complément de deux contient seulement une valeur 0, alors que son complément permet de définir à la fois un zéro positif et un zéro négatif. En ce qui concerne l'ajout de report supplémentaire, pensez à ajouter un nombre positif à un nombre négatif plus petit. En raison de la représentation du complément à un, le petit nombre négatif sera en fait assez important lorsqu'il est considéré comme une quantité non signée. L'addition des deux peut entraîner un débordement avec un bit de retenue. À la différence de l'addition non signée, cela ne signifie pas nécessairement que la valeur est trop grande pour représenter dans le numéro de complément, mais simplement que la représentation dépasse temporairement le nombre de bits disponibles. Pour compenser cela, vous ajoutez le bit de report après avoir ajouté les deux numéros de complément.
Est-ce une question de devoirs? Si oui, pensez à la façon dont vous représenteriez 0 dans un système de complément à 1.
+1 Les indices sont bons –
Complement! = Compliment. –
Carl, vous avez plus de suffisamment de rep pour corriger une faute d'orthographe. –
La représentation interne des nombres ne fait partie d'aucune de ces langues, c'est une caractéristique de l'architecture de la machine elle-même. La plupart des implémentations utilisent le complément 2 parce que l'addition et la soustraction ont la même opération binaire (les opérations signées et non signées sont identiques).
Strictement parlant, une langue pourrait faire de son mieux pour utiliser son complément si elle le voulait vraiment. Il serait lent, mais il pourrait le faire :) – bdonlan
Très bon point - habituellement ces langues exposent ce qui est sous-jacent (bien que bdonlan ait un point) –
@Carl - en fait, pour Java la représentation des entiers ** fait ** partie de la spécification de la langue. –
Il s'agit du zéro et de l'arrondi. Si vous utilisez le 1er complément, vous pouvez avoir deux zéros. Voir here pour plus d'informations.
Au moins C et C++ offrent la négation du complément 1 (qui est la même que la négation au niveau du bit) via l'opérateur ~
du langage. La plupart des processeurs - et tous les modernes - utiliser la représentation du complément de 2 pour plusieurs raisons:
- Ajout des nombres positifs et négatifs est le même que l'ajout d'entiers non signés
- Non « gaspillés » valeurs en raison de deux représentations de 0 (+0 et -0)
Edit: Le draft of C++0x ne précise pas si les types entiers signés sont le complément 1 ou complément à 2, ce qui signifie qu'il est des versions très peu probable que antérieures de C et C++ ne le préciser. Ce que vous avez observé est comportement défini par l'implémentation, qui est le complément de 2 sur au moins les processeurs modernes pour des raisons de performances.
La réponse est différente pour différentes langues. Dans le cas de C, vous pouvez en théorie implémenter le langage sur une machine à complément de 1 ... si vous pouviez encore trouver une machine complémentaire de 1 à fonctionner pour exécuter vos programmes! Utiliser le complément de 1 présenterait des problèmes de portabilité, mais c'est la norme pour C. Je ne suis pas sûr de ce que l'affaire est pour C++, mais je ne serais pas surpris si c'est la même chose. Dans le cas de Java, la spécification du langage définit des tailles et des représentations précises pour les types primitifs, ainsi qu'un comportement précis pour les opérateurs arithmétiques. Ceci est fait pour éliminer les problèmes de portabilité qui surviennent lorsque vous rendez ces implémentations spécifiques.Les concepteurs Java ont spécifié l'arithmétique du complément à 2 car toutes les architectures de processeurs modernes implémentent le complément à 2 et non les entiers à complément à 1.
Pour des raisons pour lesquelles le matériel moderne implémente le complément à 2 et non le complément à 1, jetez un oeil à (par exemple) les pages de Wikipedia sur le sujet. Voyez si vous pouvez comprendre les implications des alternatives.
Les standards C et C++ prévoient tous deux que les entiers signés soient complémentaires ou même significatifs, même si AFAIK n'a * jamais * implémenté l'un ou l'autre langage sur une telle machine (le mieux que je puisse dire, pas de CPU) a été fabriqué depuis les années 1970). – zwol
Presque tout le matériel CPU existant utilise le complément à deux, il est donc logique que la plupart des langages de programmation le fassent aussi.
C et C++ supportent son complément, si le matériel le fournit.
La représentation de l'amplitude du signe serait bien meilleure pour le code numérique. Le manque de symétrie est un vrai problème avec le complément à 2 et empêche aussi beaucoup de hacks bit utiles (orientés numériquement). Le complément de 2 introduit également des situations difficiles où une opération arithmétique peut ne pas vous donner le résultat que vous pensez qu'il pourrait. Donc, vous devez être conscient de la division, du déplacement et de la négation.
Si ce sont des devoirs - ce qui est correct - s'il vous plaît étiqueter de cette façon afin que nous puissions vous aider avec des conseils et des conseils au lieu des réponses –
qui a dit que ce sont les devoirs? – root
Java utilise le complément à 2, mais en C et C++, la représentation des types entiers signés est définie par l'implémentation. –