33 votes

Promotion de la virgule flottante : stroustrup contre compilateur - qui a raison ?

Dans la section 10.5.1 du nouveau livre de Stroustrup intitulé "The C++ Programming Language - Fourth Edition", il indique qu'avant d'effectuer une opération arithmétique, la promotion intégrale est utilisée pour créer des ints à partir de types d'entiers plus courts, et de la même manière, la promotion flottante est utilisée pour créer des doubles à partir de flottants.

J'ai confirmé la première affirmation avec le code suivant :

#include <iostream>
#include <typeinfo>

int main()
{
    short a;
    short b;
    std::cout << typeid(a + b).name() << std::endl;
}

Cela produit "int" avec vc++ et "i" avec gcc.

Mais en le testant avec des flottants au lieu de shorts, la sortie est toujours "float" ou "f" :

#include <iostream>
#include <typeinfo>

int main()
{
    float a;
    float b;
    std::cout << typeid(a + b).name() << std::endl;
}

Selon Stroustrup, il n'y a pas d'exception à la règle de promotion de la virgule flottante, donc je m'attendais à un résultat "double" ou "d".

La section mentionnée concernant les promotions est-elle erronée ou peu claire ? Et y a-t-il une différence entre C++98 et C++11 en ce qui concerne les promotions de type ?

29voto

interjay Points 51000

Je ne sais pas ce que dit exactement le livre de Stroustrup, mais selon la norme, float ne seront pas convertis en double dans ce cas. Avant d'appliquer la plupart des opérateurs arithmétiques binaires, la fonction conversions arithmétiques habituelles décrites en 5p9 sont appliquées :

  • Si l'un des opérandes est de type énumération scopée (7.2), aucune conversion n'est effectuée ; si l'autre opérande n'a pas le même type, l'expression est mal formée.
  • Si l'un des opérandes est de type long double, l'autre est converti en long double.
  • Sinon, si l'un des opérandes est double, l'autre est converti en double.
  • Sinon, si l'un des opérandes est un flottant, l'autre doit être converti en flottant.
  • Dans le cas contraire, les promotions intégrales (4.5) sont effectuées sur les deux opérandes. [...]

Les promotions intégrales sont ce qui fait que deux short à convertir en int s. Mais deux float ne seront pas convertis en double selon ces règles. Si vous ajoutez un float à un double le float sera converti en un double .

Ce qui précède est tiré de C++11. C++03 contient les mêmes règles, à l'exception de celle qui fait référence aux énumérations scopées.

6voto

Tom8128 Points 31

En attendant, Stroustrup semble reconnaître que la phrase de référence n'est pas correcte ou du moins trompeuse. Il a supprimé la phrase, concernant la promotion de la virgule flottante, de la section 10.5.1.

Veuillez consulter errata de la 3ème impression de la 4ème édition sur la page web de Stroustrup :

pg 267 : s/Similairement, la promotion en virgule flottante est utilisée pour créer des doubles à partir de flottants///.

(Remarques : L'expression s/regexp/replacement/ est similaire à sed sémantique des outils unix. Il recherche le motif regexp et le remplace par remplacement . Rien dans notre cas.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X