11
votes

Pourquoi INT Plus UINT retourne uint uint?

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;
}


4 commentaires

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!


+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?


3 Réponses :


15
votes

si par "devrait-il être" tu veux dire "mon compilateur se compore-t-il selon la norme": oui .

C ++ 2003: article 5, paragraphe 9:

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:

  • bla
  • sinon, bla ,
  • Autreseise, bla , ...
  • Sinon, si l'un ou l'autre est non signé, l'autre doit être convertie en non signé.

    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.


2 commentaires

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 entraînera une valeur positive.



2
votes

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 ... 1001 et ... 0101 , le résultat sera ... 1110 . Si on ajoute ... 1111 et ... 0001 , le résultat sera ... 0000 ; Si on soustrait ... 0001 de ... 0000 Le résultat sera ... 1111 . 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).

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 ... 00010110 "dans" le nombre dont les bits inférieurs sont ... 00010110


1 commentaires

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 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; , après avoir calculé y * z, est nécessaire pour ignorer tous les 16 bits inférieurs du résultat.



1
votes

Il est probable que le comportement découle de la logique derrière les types de pointeur (emplacement de la mémoire, par exemple std ::ze_t ) plus une différence de localisation de mémoire ( std :: pTRDIFF_T ) est également un emplacement de mémoire.

En d'autres termes, STD :: Taille_T = STD :: Taille_T + STD :: PTRIFF_T .

Lorsque cette logique est traduite en types de sous-couche, ce moyen, non signé long = non signé long + long ou non signé = non signé + int . .

L'explication "Autre" de @supercat est également éventuellement correcte.

Ce qui est clair est que non signé integer n'a pas été conçu ou ne doit pas être interprété comme numéros positifs mathématiques , pas même en principe. Voir https://www.youtube.com/watch?v=WVTFGA6XJDU


0 commentaires