est-ce toujours techniquement correct:
-l
7 Réponses :
La plupart des ordinateurs utilisent aujourd'hui une échelle de numéro de deux compléments, ce qui signifie que la partie négative est une plus grande que la positive, par exemple de -128 à 127. Cela signifie que si vous pouvez représenter le nombre positif, le nombre négatif que vous pouvez représenter le numéro négatif. numéro sans inquiétude. P>
Je pense qu'il demande au cas contraire; à savoir s'il s'agit de convertir un nombre négatif donné à un positif pourrait déborder dans certains cas.
Cela ne signifie-t-il pas que lors de l'ABS (-128), il tentera de construire l'entier +128, ce qui n'est pas représentable?
@bluescami: Oui et le +128 (dans ce système imaginaire 8 bits Int) débordent à -128.
Mais autant que je me souvienne, des débordements entier signés sont un comportement indéfini en C / C ++?
@Justin: Ah, aurait dû lire la question plus attentivement alors. Owell J'espère qu'il a appris quelque chose de la réponse dans tous les cas.
@bluescami: HM, je pense qu'il est défini à envelopper, -129 devient +127 et +128 devient -128, etc. Peut être confondu cependant.
Oui, il déborde, à lui-même.
#include <stdio.h>
#include <limits.h>
int main(int argc, char**argv) {
int foo = INT_MIN;
if (-foo == INT_MIN) printf("overflow\n");
return 0;
}
Est-ce défini par la norme?
Ou plutôt, il déborde de zéro. Et zéro se trouve avoir la belle propriété qu'il n'est ni négative ni positive. Essayer donc de trouver la valeur négative de zéro serait bien sûr que vous remontiez-vous directement à zéro.
Si cela déborde, le comportement est indéfini.
@Roland Illig: Vous avez une citation pour cela? Je crois aussi que c'est juste comment fonctionne le complément de deux. Je ne sais pas à quel point les normes C ou C ++ sont liées au complément de deux.
@slebetman: Non, le --Foo produit une valeur globale légale; Le -foo déborde. Mais parce que c en ce qui concerne l'opérateur, ne faisant pas partie de la constante, "-2147483648" peut provoquer des avertissements de complétation environ 2147483648 ne constituant pas une constante INT valide. J'ai enlevé le --Foo alors quels débordent ne sont pas confus.
Ah, j'ai raté que certaines pensées foo deviennent 0; clarifié le code à nouveau.
Je n'ai pas de citation à portée de main, mais je sais que C n'exige pas le complément de deux deux, et je pense que c ++ suit c à cet égard. Quand je suis à la maison, je peux citer l'ISO C99.
C99 §6.5 / 5: "Si une condition exceptionnelle se produit lors de l'évaluation d'une expression (c'est-à-dire si le résultat n'est pas défini mathématiquement ou non dans la gamme de valeurs représentables pour son type), le comportement est indéfini. "
Si vous souhaitez éviter le débordement, vous devez d'abord lancer n code> à un INT non signé, puis appliquez le moins le moins à celui-ci. unsigned abs(int n) {
if (n >= 0)
return n;
return -((unsigned)n);
}
Je ne suis pas sûr de comprendre cela complètement ... ce comportement s'appuie-t-il sur le complément de deux?
Non ça ne le fait pas. Il fonctionne dans n'importe quel environnement conforme à l'ISO C90 ou à l'ISO C99, et aucune de ces normes ne nécessite que les arithmétiques complémentaires de deux. L'astuce consiste à éviter toute dépendance sur les entiers négatifs en calculant complètement le cas intéressant dans les arithmétiques non signés.
OK, peut-être que je comprends lentement cela ... laissez-moi essayer: 1) après la distribution, la valeur non signée est congruente Modulo 2 ** NBITS à la valeur d'origine 2) avec l'opérateur Minus une autre opération MODULO est effectuée.
Ok maintenant, j'ai également eu la partie moins, citant de la norme C ++: "Le négatif d'une quantité non signée est calculé en soustrayant sa valeur de 2 ** N, où n est le nombre de bits dans l'opérande promu".
ERR, est le comportement de la coulée des INT négatifs de non signé plus garantis que de simplement permettre le débordement?
Apparemment donc, au moins en C ++ (4.7.2): "Si le type de destination est non signé, la valeur résultante est le plus non signé entier congruant à la source entier (modulo 2 ** n où n est le nombre de bits utilisés pour représenter le type non signé) ".
Ensuite, c'est la voie à suivre, apparemment.
Peut-être que cela pourrait faire face à la plage symétrique de 2's-compléments numéros:
Cela fonctionnerait en supposant que _max et _min diffère au plus par 1 (mais bien sûr peut être généralisé).
Ils diffèrent au plus un. C permet seulement 3 choix possibles de représentation signée: twos complément, complément et signe / magnitude (avec des différences de 1, 0 et 0, respectivement).
@R .. Merci pour l'info, je voulais demander que tôt ou tard :)
@bruce: Vous avez vos types / limites incompatibles. Changer long_min code> à int_min code> et long_max code> à int_max code>. Vous devriez probablement aussi corriger le premier cas d'utiliser - (non signé) int_min code> au lieu de int_max + 1ul code> de sorte qu'il fonctionne sur n'importe quelle représentation.
@R .. merci. Merci. Mais je me demande la différence entre "int_max + 1" et "-int_max", n'est-ce pas l'ancien travail?
-int_min code> est un comportement indéfini dans le cas de twos complément, car la valeur de l'application de la négation unaire sur int_min code> est supérieure à int_max code> et donc un débordement . int_max + 1 code> est toujours un comportement indéfini car il déborde. int_max + 1U code> est bien défini cependant.
Très bonne question, qui expose les différences entre C89, C99 et C ++. Il s'agit donc d'un commentaire sur ces normes.
en C89, où n est un int: p> n'est pas bien défini pour tous les n: il n'y a pas de restriction sur la conversion de signé ou non signé INT sauf que la représentation d'un Int non négatif signé est identique à celle d'un Int non signé de la même valeur, à condition que la valeur soit représentative. p> Ceci a été considéré comme un défaut et en C99, c ++ s'est déroulée de fournir une meilleure spécification, mais elle souffre de la même défaut de définition circulaire. P> à peu près à peine, la représentation d'une valeur V est une gamme de caractères non signés ( v) éléments. Un caractère non signé a une puissance de deux nombres d'éléments et doit être suffisamment grosse pour s'assurer qu'elle code fidèlement toute structure de données aliasée. Le nombre de bits dans un caractère non signé est bien défini comme le journal binaire du nombre de valeurs représentées. P> Le nombre de bits de toute valeur non signée est similaire bien défini s'il a une puissance de deux nombre de Valeurs de 0 à 2 ^ n-1, via le schéma de codage de position canonique. P> Malheureusement, le Comité souhaitait demander s'il y avait des "trous" dans la représentation. Par exemple, pourriez-vous avoir un entier 31 bits sur une machine X86? Je dis malheureusement, car il s'agit d'une question mal formée, et la réponse est également inappropriée. P> La manière appropriée de poser cette question est de demander si la représentation est pleine. Il n'est pas une représentation est pleine s'il s'agit d'une surposition , c'est-à-dire que c'est sur toute la gamme de l'espace de représentation. Si la représentation est pleine, il n'y a pas de "trous", c'est-à-dire des bits inutilisés. Cependant, ce n'est pas tout. Une représentation de 255 valeurs à une matrice de 8 bits ne peut pas être pleine, mais il n'y a pas de bits non utilisés. Il n'y a pas de trous. P> Le problème est-ce: Considérez un Int non signé, il existe alors deux représentations distinctes sur les bits. Il existe une matrice bien définie de bits de journalisation 2 bits déterminés à partir du codage canonique, puis il y a la maquette de bits de la représentation physique donnée par l'aliasing d'une gamme de charcuterie non signée. Même si cette représentation est pleine, il est Nous savons tous que les "bits d'ordre élevé" de la représentation logique peuvent être à une extrémité de la représentation physique sur certaines machines et l'autre sur d'autres machines: elle s'appelle Endian-Ness. Mais en fait, il n'y a aucune raison que les bits ne pouvaient être permutés dans aucun ordre du tout, il n'y a aucune raison que les bits devraient aligner du tout! Il suffit d'envisager d'ajouter 1 modulo la valeur maximale plus 1 comme représentant de la voir. P> Alors maintenant, le problème est que pour les entiers signés, il y a Parce que cela n'était pas terminé, la norme C99 contient une gibberish non normative et par conséquent toutes les règles de comportement de Les conversions entier signées et non signées sont également une gibberish non normative. P> Par conséquent, il n'est pas clair que p> produira réellement le résultat souhaité pour des valeurs négatives . p> p>
Spécifier les représentations entière comme cela a été fait aurait pu être une erreur, mais vous vous trompez ici: la conversion de la signature à une non signée est définie en termes de valeurs ("ajoutant ou soustrayant à plusieurs reprises une plus que la valeur maximale pouvant être représentée dans le nouveau Tapez ") et donc bien défini
Votre discours peut avoir mérite, mais la conclusion est fausse. La norme spécifie absolument le résultat de la conversion à un non signé comme réduction modulo une plus la valeur maximale possible dans le type de destination.
Il n'existe pas de débordement de nombres entiers non signés dans C. Arithmétique pour eux est clairement défini comme un calcul modulo leur max + 1, ils peuvent "envelopper" mais techniquement, cela n'est pas considéré comme un débordement. Donc, la partie de conversion de votre code est bien, bien que dans des cas extrêmes, vous pourriez rencontrer des résultats surprenants.
Le seul point où vous pourriez avoir débordement dans votre code est le - code> d'un type signé. Il existe exactement une valeur pour les types signés qui pourraient ne pas avoir de contrepartie positive, la valeur minimale. En fait, pour que vous faudriez faire un chèque spécial, E.g for int code> p>
Cela devrait éviter les comportements indéfinis et travailler avec toutes les représentations de INT signé (Complément 2 de 2, Complément, signe et magnitude de 2):
_myabs:
movl 4(%esp), %eax
cltd
xorl %edx, %eax
subl %edx, %eax
ret
Il y a un plus grand nombre de twos-compléments négatifs que positif, donc oui, il peut déborder.