web-dev-qa-db-fra.com

Est-ce qu'on double promouvoir chaque int de l'équation à doubler?

La présence d’un type de données à virgule flottante (par exemple, double) garantit-elle que toutes les opérations mathématiques +, -, *, /,%, etc. supposent des opérandes doubles?

Si l'histoire est plus compliquée que cela, existe-t-il une ressource décrivant ces règles? Ne devrais-je pas poser de telles questions et toujours explicitement transtyper int en double lorsque le résultat de l'équation est double. Voici quelques équations auxquelles je pense. À dessein, je n'ai pas compilé et exécuté sur mon système, car c'est le type de chose qui pourrait dépendre du compilateur.

int a(1), b(2), c(3);
double d(4.);
double result1 = a + b/d + c; // equal to 4 or to 4.5?
double result2 = (a + b)/d + c; // equal to 3 or to 3.75?    
double result3 = a/b + d; // equal to 4 or to 4.5?
14
Alan Turing

À dessein, je n'ai pas compilé et exécuté sur mon système, car c'est le type de chose qui pourrait dépendre du compilateur.

Ceci dépend de not du compilateur. C++ définit clairement l'ordre de ces opérations et comment elles sont converties.

Le mode de conversion dépend de l’ordre des opérations.

double result1 = a + b / d + c; // equal to 4 or to 4.5?

Dans cet exemple, la division se produit en premier. Comme il s'agit d'un int divisé par un double, le compilateur le gère en convertissant l'int en un double. Ainsi, le résultat de b / d est un double.

La prochaine chose que fait C++ est d’ajouter a au résultat de b / d. Ceci est un int ajouté à un double, donc il convertit l'int en un double et ajoute, aboutissant à un double. La même chose arrive avec c.

double result3 = a / b + d; // equal to 4 or to 4.5?

Dans cet exemple, la division est traitée en premier. a et b sont tous les deux ints, donc aucune conversion n'est effectuée. Le résultat de a / b est de type int et vaut 0.

Ensuite, le résultat est ajouté à d. Ceci est un int plus un double, donc C++ convertit l'int en un double et le résultat est un double.

Même si un double est présent dans cette expression, a / b est évalué en premier et le double ne signifie rien tant que l'exécution n'atteint pas le double. Par conséquent, la division entière se produit.

Je trouve les règles de promotion et de conversion assez complexes. Généralement, les nombres de type entier (short, int, long) sont promus en équivalents à virgule flottante (float, double). Mais les choses sont compliquées par les différences de taille et de signe.

Voir cette question pour plus de détails sur la conversion.

32
Slix

Est-ce qu'une double promeut chaque int dans l'équation en double?

Non, seulement le résultat d'une seule opération (en ce qui concerne la priorité).

double result1 = a + b/d + c; // equal to 4 or to 4.5?

4.5.

double result2 = (a + b)/d + c; // equal to 3 or to 3.75?

3,75.

double result3 = a/b + d; // equal to 4 or to 4.5?

4.

8
user529758

Vous devez tenir compte de la priorité de chaque opérateur, vous devez penser comme un analyseur:

double result1 = a + b/d + c; // equal to 4 or to 4.5?

C’est comme a + (b/d) + c parce que l’opérateur '/' a la priorité la plus grande. Ensuite, peu importe la nature de ces 2 opérations qui est faite en premier, car l’opérande virgule flottante est au milieu, et "infecte" les autres opérandes et les fait doubler.Alors c'est 4.5. 

double result2 = (a + b)/d + c; // equal to 3 or to 3.75?  

Idem ici, c’est comme ((a + b)/d) + c, donc a + b est 3, que 3 devient un nombre à virgule flottante car on passe au double, car c’est le dividende de d, qui est un double, donc c'est 0,75 + 3, c'est-à-dire 3,75. 

double result3 = a/b + d; // equal to 4 or to 4.5?

C'est comme (a/b) + d, donc a/b est égal à zéro et d est égal à 4, il est donc égal à 4. Un analyseur syntaxique effectue toutes les opérations par ordre de priorité, de sorte que vous puissiez savoir exactement quel sera le résultat. résultat de l'expression.

2
Ramy Al Zuhouri

En règle générale, si l'un des opérandes d'un opérateur binaire est à virgule flottante et que l'autre est un entier, l'entier est converti en virgule flottante et le résultat est un nombre à virgule flottante.

Dans une expression composée comportant plusieurs sous-expressions, chaque opérateur est traité individuellement, à l'aide des règles de priorité que vous connaissez probablement. Ainsi, dans a*b + c*d, a*b est évalué, et c*d est évalué et les résultats sont additionnés. Tout ce qui est dans c*d n'a aucun effet dans a*b et vice-versa.

C++ est bien sûr compliqué et les opérateurs définis par l'utilisateur peuvent avoir d'autres comportements.

La ressource faisant autorité qui définit les règles est la norme C++. La norme est assez grande et technique. Vous préférerez peut-être examiner le standard C en premier. Voir cette réponse pour des liens vers les normes. Tout bon livre sur C ou C++ devrait décrire les conversions de types par défaut et l’évaluation des expressions.

1
Eric Postpischil