Il est bien connu qu'en C, les littéraux à virgule flottante (par exemple 1.23
) ont le type double
. En conséquence, tout calcul qui les implique est promu au double.
Je travaille sur un système embarqué en temps réel qui a une unité à virgule flottante qui prend en charge uniquement les nombres à simple précision (float
). Toutes mes variables sont float
, et cette précision est suffisante. Je n'ai pas besoin (ni ne peux me permettre) double
du tout. Mais chaque fois que quelque chose comme
if (x < 2.5) ...
est écrit, une catastrophe se produit: le ralentissement peut aller jusqu'à deux ordres de grandeur. Bien sûr, la réponse directe est d'écrire
if (x < 2.5f) ...
mais c'est tellement facile à manquer (et difficile à détecter jusqu'à trop tard), surtout quand une valeur de "configuration" est #define
'd dans un fichier séparé par un développeur moins discipliné (ou tout simplement nouveau).
Donc, existe-t-il un moyen de forcer le compilateur à traiter tous les littéraux (virgule flottante) comme des flottants, comme avec le suffixe f
? Même si c'est contre les spécifications, je m'en fiche. Ou d'autres solutions? Le compilateur est gcc, soit dit en passant.
-fsingle-precision-constant
peut être utilisé. Il provoque le chargement de constantes à virgule flottante en simple précision, même si ce n'est pas exact.
Remarque - Cela utilisera également des constantes de précision simple dans les opérations sur les variables de double précision.
Utilisez plutôt des avertissements: -Wdouble-promotion
met en garde contre implicite float to double promotion, comme dans votre exemple. -Wfloat-conversion
vous avertira des cas où vous pouvez encore affecter des doubles à des flottants.
C'est une meilleure solution que de forcer simplement des valeurs doubles à la valeur flottante la plus proche. Votre code à virgule flottante est toujours conforme et vous n'aurez aucune mauvaise surprise si une valeur double contient une valeur positive, disons inférieure à FLT_DENORM_MIN
(en supposant IEEE-754) ou supérieur à FLT_MAX
.
Vous pouvez convertir les constantes définies en (float)
partout où ils sont utilisés, l'optimiseur doit faire son travail. Il s'agit d'une solution portable.
#define LIMIT 2.5
if (x < (float)LIMIT) ...
Le -Wunsuffixed-float-constants
L'indicateur pourrait également être utilisé, peut-être combiné avec certaines des autres options de la réponse acceptée ci-dessus. Cependant, cela n'attrapera probablement pas les constantes non suffixées dans les en-têtes du système. Aurait besoin d'utiliser -Wsystem-headers
pour les attraper aussi. Pourrait générer beaucoup d'avertissements ...