Je veux mieux savoir quand je devrais lancer. Quelles sont les règles de conversion de type implicite en C ++ lors de l'ajout, de la multiplication, etc. Par exemple,
int + float = ?
int * float = ?
float * int = ?
int / float = ?
float / int = ?
int / int = ?
int ^ float = ?
etc...
L'expression sera-t-elle toujours évaluée comme le type le plus précis? Les règles diffèrent-elles pour Java? Veuillez me corriger si j'ai formulé cette question de manière inexacte.
^
XOR.Réponses:
En C ++, les opérateurs (pour les types POD) agissent toujours sur les objets du même type.
Ainsi, s'ils ne sont pas identiques, l'un sera promu pour correspondre à l'autre.
Le type du résultat de l'opération est le même que les opérandes (après conversion).
Remarque. La taille minimale des opérations est de
int
. Doncshort
/char
sont promusint
avant que l'opération ne soit effectuée.Dans toutes vos expressions, le
int
est promu en afloat
avant que l'opération ne soit effectuée. Le résultat de l'opération est unfloat
.la source
char
. Si la valeur dechar + char
est affectée à achar
, alors il peut simplement effectuer l'arithmétiquechar
et, par exemple, faire un tour. Mais si le résultat est assigné,int
il doit faire l'arithmétique dans un type suffisamment grand pour obtenir le résultat correct quand il est supérieur àCHAR_MAX
.((int) 4) - ((unsigned int) 5)
se traduira4294967295
par des entiers 32 bits et des entiers non signés 32 bits.Opérations arithmétiques impliquant des
float
résultats dansfloat
.Pour une réponse plus détaillée. Regardez ce que dit la section §5 / 9 du standard C ++
la source
double
nilong double
.long long
etunsigned long
non abordé ici.float
n'a pas assez de bits dans la mantisse (24 bits pour IEEE-754 ) pour un 32 bitsint
, il peut donc y avoir une perte de données. Un 64 bitsdouble
devrait être très bien.Puisque les autres réponses ne parlent pas des règles en C ++ 11, en voici une. De la norme C ++ 11 (projet n3337) §5 / 9 (a souligné la différence):
Voir ici pour une liste fréquemment mise à jour.
la source
Cette réponse est en grande partie dirigée vers un commentaire de @ RafałDowgird:
Gardez à l'esprit que la norme C ++ a la règle primordiale «comme si». Voir section 1.8: Exécution du programme:
Le compilateur ne peut pas définir une
int
taille de 8 bits, même si elle était la plus rapide, car la norme impose un minimum de 16 bitsint
.Par conséquent, dans le cas d'un ordinateur théorique avec des opérations 8 bits ultra-rapides, la promotion implicite vers
int
pour l'arithmétique pourrait avoir une importance. Cependant, pour de nombreuses opérations, vous ne pouvez pas dire si le compilateur a réellement effectué les opérations avec la précision de anint
puis les a converties en achar
pour les stocker dans votre variable, ou si les opérations ont été effectuées dans char tout au long.Par exemple, considérez
unsigned char = unsigned char + unsigned char + unsigned char
, où l'addition déborderait (supposons une valeur de 200 pour chacun). Si vous êtes promuint
, vous obtiendrez 600, qui seraient alors implicitement convertis en ununsigned char
, qui encapsulerait le modulo 256, donnant ainsi un résultat final de 88. Si vous ne faisiez pas de telles promotions, vous devrez encapsuler entre les premières deux ajouts, ce qui réduirait le problème de200 + 200 + 200
à144 + 200
, qui est 344, qui se réduit à 88. En d'autres termes, le programme ne connaît pas la différence, donc le compilateur est libre d'ignorer le mandat pour effectuer des opérations intermédiairesint
si les opérandes ont un classement inférieur àint
.Cela est vrai en général pour l'addition, la soustraction et la multiplication. Ce n'est pas vrai en général pour la division ou le module.
la source
Si vous excluez les types non signés, il existe une hiérarchie ordonnée: signé char, short, int, long, long long, float, double, long double. Tout d'abord, tout ce qui précède int dans ce qui précède sera converti en int. Ensuite, dans une opération binaire, le type classé le plus bas sera converti en type le plus élevé et les résultats seront le type du type le plus élevé. (Vous noterez que, à partir de la hiérarchie, chaque fois qu'un type virgule flottante et un type intégral sont impliqués, le type intégral sera converti en type virgule flottante.)
Le non signé complique un peu les choses: cela perturbe le classement, et des parties du classement deviennent implémentées. Pour cette raison, il est préférable de ne pas mélanger signé et non signé dans la même expression. (La plupart des experts C ++ semblent éviter les non-signés, sauf si des opérations au niveau du bit sont impliquées. C'est du moins ce que recommande Stroustrup.)
la source
int
pour un nombre qui n'a jamais besoin d'être négatif est un gaspillage complet de 50% de la plage disponible. Je ne suis certainement pas Stroustrup, mais je l'utiliseunsigned
par défaut etsigned
uniquement lorsque j'ai une raison.bool in_order(vector<T> vec) { for ( int i = 0; i < size() - 1; ++i) { if (vec[i + 1] < vec[i]) return false; } return true;
et vous seriez ennuyé de constater qu'il se bloque pour les vecteurs vides parce que size () - 1 renvoie 18446744073709551615.Ma solution au problème a obtenu WA (mauvaise réponse), puis j'ai changé l'un des
int
enlong long int
et cela a donné AC (accepter) . Auparavant, j'essayais de le fairelong long int += int * int
, et après je l'ai rectifiélong long int += long long int * int
. J'ai trouvé sur Google,1. Conversions arithmétiques
Conditions de conversion de type:
Conditions remplies ---> Conversion
Les deux opérandes sont de type double long . ---> L'autre opérande est converti en type long double .
La condition précédente n'est pas remplie et l'un ou l'autre des opérandes est de type double . ---> L'autre opérande est converti en type double .
Les conditions précédentes ne sont pas remplies et l'un ou l'autre des opérandes est de type float . ---> L'autre opérande est converti en type float .
Conditions précédentes non remplies (aucun des opérandes n'est de type flottant). ---> Les promotions intégrales sont effectuées sur les opérandes comme suit:
2. Règles de conversion d'entiers
Les types entiers plus petits que int sont promus lorsqu'une opération est effectuée sur eux. Si toutes les valeurs du type d'origine peuvent être représentées sous la forme d'un int, la valeur du type le plus petit est convertie en un int; sinon, il est converti en un entier non signé. Les promotions entières sont appliquées dans le cadre des conversions arithmétiques habituelles de certaines expressions d'argument; opérandes des opérateurs unaires +, - et ~; et les opérandes des opérateurs de décalage.
Rang de conversion entier:
long long int
sera supérieur au grade delong int
, qui sera supérieur au grade deint
, qui sera supérieur au grade deshort int
, qui sera supérieur au grade designed char
.char
sera égal au rang designed char
etunsigned char
.Conversions arithmétiques usuelles:
la source
Tout le chapitre 4 parle des conversions, mais je pense que vous devriez surtout vous intéresser à celles-ci:
4.5 Promotions intégrales [conv.prom]
Une rvalue de type char, signed char, unsigned char, short int ou unsigned short int peut être convertie en une rvalue de type int si int peut représenter toutes les valeurs du type source; sinon
, la rvalue source peut être convertie en une rvalue de type unsigned int.
Une rvalue de type wchar_t (3.9.1) ou un type d'énumération (7.2) peut être convertie en une rvalue du premier
des types suivants qui peut représenter toutes les valeurs de son type sous-jacent: int, unsigned int,
long ou unsigned longue.
Une rvalue pour un champ binaire intégral (9.6) peut être convertie en une rvalue de type int si int peut représenter toutes
les valeurs du champ binaire; sinon, il peut être converti en unsigned int si unsigned int peut représenter
renvoyer toutes les valeurs du champ de bits. Si le champ de bits est encore plus grand, aucune promotion intégrale ne s'applique à lui. Si le
champ de bits a un type énuméré, il est traité comme toute autre valeur de ce type à des fins de promotion.
Une rvalue de type bool peut être convertie en une rvalue de type int, avec false devenant zéro et true
devenant un.
Ces conversions sont appelées promotions intégrales.
4.6 Promotion en virgule flottante [conv.fpprom]
Une rvalue de type float peut être convertie en une rvalue de type double. La valeur est inchangée.
Cette conversion est appelée promotion en virgule flottante.
Par conséquent, toutes les conversions impliquant float - le résultat est float.
Uniquement celui impliquant les deux int - le résultat est int: int / int = int
la source
Le type de l'expression, lorsque les deux parties ne sont pas du même type, sera converti en la plus grande des deux. Le problème ici est de comprendre lequel est plus grand que l'autre (cela n'a rien à voir avec la taille en octets).
Dans les expressions dans lesquelles un nombre réel et un nombre entier sont impliqués, l'entier sera promu en nombre réel. Par exemple, dans int + float, le type de l'expression est float.
L'autre différence est liée à la capacité du type. Par exemple, une expression impliquant un int et un long int sera de type long int.
la source
long
est "plus grand" que afloat
mais quel est le type delong
+float
?Caveat!
Les conversions se produisent de gauche à droite.
Essaye ça:
la source
j + i * k
donnerait 101.