int Plus non signé int renvoie un Int non signé. Devrait-il être tel?
Considérez ce code: P>
#include <boost/static_assert.hpp> #include <boost/typeof/typeof.hpp> #include <boost/type_traits/is_same.hpp> class test { static const int si = 0; static const unsigned int ui = 0; typedef BOOST_TYPEOF(si + ui) type; BOOST_STATIC_ASSERT( ( boost::is_same<type, int>::value ) ); // fails }; int main() { return 0; }
3 Réponses :
si par "devrait-il être" tu veux dire "mon compilateur se compore-t-il selon la norme": oui fort>. p>
C ++ 2003: article 5, paragraphe 9: p>
De nombreux opérateurs binaires qui s'attendent à ce que les opérandes de type arithmétique ou d'énumération provoquent des conversions et un rendement
types de résultat de la même manière. Le but est de donner un type commun, qui est également le type de résultat.
Ce modèle s'appelle les conversions arithmétiques habituelles, définies comme suit: p>
si par "si" si vous voulez dire "le monde serait un meilleur endroit si ce n'est pas": je ne suis pas compétent pour répondre à cela. P>
Je suis sûr que le comité de normes C ++ vise à rendre le monde meilleur un meilleur endroit, de sorte que "si c'est" je veux dire "" pourquoi le monde ne serait pas un meilleur endroit si non ".
@Vahagn - alors c'est tellement (int) 0x70000000 + (non signé INT) 0x70000000 code> entraînera une valeur positive.
Les types d'entiers non signés se comportent principalement en tant que membres d'une bague algébrique abstraite d'emballage des valeurs équivalentes 2 ^ n; On peut afficher un entier non signé N-Bit non signé non plus comme représentant un entier particulier, mais plutôt l'ensemble de tous les entiers ayant une valeur particulière dans les bits inférieurs. Par exemple, si l'on ajoute ensemble deux nombres binaires dont les 4 derniers chiffres sont Les seuls endroits où les types d'entiers non signés ne parviennent pas à se comporter en tant que membres d'une bague algébrique d'emballage sont lorsqu'ils participent aux comparaisons, sont utilisés dans la division numérique (qui implique des comparaisons) ou sont promus à d'autres types. Si le seul moyen de convertir un type d'entier non signé à quelque chose de plus important consistait à utiliser un opérateur ou une fonction à cet effet, l'utilisation d'un tel opérateur ou d'une fonction pourrait préciser qu'elle faisait des hypothèses sur les bits supérieurs (par exemple, le tournant " dont les bits inférieurs sont ... 1001 CODE> et
... 0101 CODE>, le résultat sera
... 1110 code>. Si on ajoute
... 1111 code> et
... 0001 code>, le résultat sera
... 0000 code>; Si on soustrait
... 0001 code> de
... 0000 code> Le résultat sera
... 1111 code>. Notez que les concepts de débordement ou de débordement ne veulent pas vraiment dire quoi que ce soit, car les valeurs supérieures des opérandes sont inconnues et que les valeurs supérieures du résultat ne sont aucun intérêt. Notez également que l'ajout d'un entier signé dont les bits supérieurs sont connus de celui dont les bits supérieurs sont "ne savent pas / ne pas s'en soucier" devrait donner un nombre dont les bits supérieurs "ne savent pas / ne s'en soucient pas" (qui est ce que les types d'entiers non signés se comportent principalement comme). P>
... 00010110 code> "dans" le nombre dont les bits inférieurs sont
... 00010110 dont les bits supérieurs sont tous des zéros). Malheureusement, C ne pas fais cela. Ajout d'une valeur signée à une valeur non signée de la taille égale donne une valeur non signée de taille similaire (ce qui est logique avec l'interprétation de valeurs non signées ci-dessus), mais l'ajout d'un entier signé plus grand à un type non signé entraînera le compilateur silencieusement Supposons que tous les bits supérieurs de ces derniers sont des zéros. Ce comportement peut être particulièrement vexé dans les cas où, selon les règles de promotion des compilateurs, certains compilateurs peuvent juger deux expressions comme ayant la même taille, tandis que d'autres peuvent les voir comme des tailles différentes. < / p>
Downvoter: soin de commenter? Les types d'entiers non signés sont souvent utilisés pour calculer efficacement les bits inférieurs et ignorer les bits supérieurs d'une valeur plus grande (par exemple à l'aide d'une valeur uint8_t code> sur la somme d'un groupe d'octets). Ma description ne correspond pas à la normale, mais elle est cohérente avec une telle utilisation et représente l'intention de la plupart des programmeurs qui repose sur un comportement d'emballage inteer non signé; Il est également cohérent avec le code généré du compilateur où par exemple.
uint16_t x, y, z; ... x = y * z; code>, après avoir calculé y * z, est nécessaire pour ignorer tous les 16 bits inférieurs du résultat.
Il est probable que le comportement découle de la logique derrière les types de pointeur (emplacement de la mémoire, par exemple En d'autres termes, Lorsque cette logique est traduite en types de sous-couche, ce moyen, L'explication "Autre" de @supercat est également éventuellement correcte. P>
Ce qui est clair est que std ::ze_t code>) plus une différence de localisation de mémoire (
std :: pTRDIFF_T code> ) est également un emplacement de mémoire. P>
STD :: Taille_T = STD :: Taille_T + STD :: PTRIFF_T CODE>. P>
non signé long = non signé long + long code> ou
non signé = non signé + int p>. p>.
non signé code> integer n'a pas été conçu ou ne doit pas être interprété comme numéros positifs mathématiques em>, pas même en principe. Voir https://www.youtube.com/watch?v=WVTFGA6XJDU p>
Peut-être devriez-vous demander aux gars qui ont conçu la langue.
Il y a un autre message sur le site sur le même sujet que vous pouvez trouver ici: http: //stackoverflow.com/questions/2084949/Arithmetic-Opérat ions-in-non signé-et -signed-and -signed-intégers J'espère que cela vous aide! B>
+1 pour fournir un cas de test complet. SSCCE.ORG
Dupliqué possible de Comment les règles de promotion fonctionnent-elles lorsque la signature de chaque côté d'un opérateur binaire diffère?