«F» après le nombre


102

Qu'indique faprès les chiffres? Est-ce de C ou Objective-C? Y a-t-il une différence à ne pas ajouter cela à un nombre constant?

CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);

Pouvez-vous expliquer pourquoi je n'écrirais pas simplement:

CGRect frame = CGRectMake(0, 0, 320, 50);

Réponses:


88
CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);

utilise des constantes flottantes. (La constante 0.0 déclare généralement un double en Objective-C; mettre un f à la fin - 0.0f - déclare la constante comme un flottant (32 bits).)

CGRect frame = CGRectMake(0, 0, 320, 50);

utilise des entiers qui seront automatiquement convertis en flottants.

Dans ce cas, il n'y a pas de différence (pratique) entre les deux.


24
Théoriquement, le compilateur peut ne pas être assez intelligent pour les convertir en float au moment de la compilation, et ralentirait l'exécution avec quatre conversions int-> float (qui sont parmi les conversions les plus lentes). Bien que dans ce cas, ce soit presque sans importance, il est toujours préférable de spécifier correctement f si nécessaire: dans une expression, une constante sans le bon spécificateur peut forcer la conversion de l'expression entière en double, et si elle est dans une boucle serrée, la performance peut être perceptible.
Matteo Italia

60

En cas de doute, vérifiez la sortie de l'assembleur. Par exemple, écrivez un petit extrait minimal, c'est-à-dire comme celui-ci

#import <Cocoa/Cocoa.h>

void test() {
  CGRect r = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);
  NSLog(@"%f", r.size.width);
}

Puis compilez-le en assembleur avec l' -Soption.

gcc -S test.m

Enregistrez la sortie de l'assembleur dans le test.sfichier et supprimez- .0fla des constantes et répétez la commande de compilation. Puis faites undiff des nouveaux test.set des précédents. Pensez que cela devrait montrer s'il existe de réelles différences. Je pense que trop de gens ont une vision de ce qu'ils pensent que fait le compilateur, mais à la fin de la journée, il faut savoir comment vérifier les théories.


11
La sortie s'est avérée identique pour moi, même sans aucun -O. Je suis sur i686-apple-darwin10-gcc-4.2.1 (GCC)
kizzx2

2
J'ai essayé l'exemple ci-dessus avec la version 7.0.0 de LLVM (clang-700.0.65) x86_64-apple-darwin15.0.0 et les fichiers .out étaient également identiques.
Nick

43

Parfois, il y a une différence.

float f = 0.3; /* OK, throw away bits to convert 0.3 from double to float */
assert ( f == 0.3 ); /* not OK, f is converted from float to double
   and the value of 0.3 depends on how many bits you use to represent it. */
assert ( f == 0.3f ); /* OK, comparing two floats, although == is finicky. */

26

Il indique à l'ordinateur qu'il s'agit d'un nombre à virgule flottante (je suppose que vous parlez de c / c ++ ici). S'il n'y a pas de f après le nombre, il est considéré comme un double ou un entier (selon s'il y a une décimale ou non).

3.0f -> float
3.0 -> double
3 -> integer

cette convention fait-elle partie du standard C ++ ou se trouve-t-elle dans le compilateur?
jxramos

1
Autant que je sache, cela fait partie de la norme (quelqu'un me corrige si je me trompe). La référence la plus rapide que j'ai pu trouver est open-std.org/jtc1/sc22/open/n2356/lex.html#lex.fcon , mais il y a probablement des références plus à jour si vous voulez les chercher.
NickLH

5

Un littéral à virgule flottante dans votre code source est analysé comme un double. L'affecter à une variable de type float perdra en précision. Beaucoup de précision, vous jetez 7 chiffres significatifs. Le postfix "f" vous permet de dire au compilateur: "Je sais ce que je fais, c'est intentionnel. Ne me dérangez pas à ce sujet".

Les chances de produire un bogue ne sont pas si petites que ça. Beaucoup de programmes ont échoué sur une comparaison en virgule flottante mal conçue ou en supposant que 0,1 est exactement représentable.


4

Le fdont vous parlez est probablement destiné à indiquer au compilateur qu'il fonctionne avec un flotteur. Lorsque vous omettez lef , il est généralement traduit en double.

Les deux sont des nombres à virgule flottante, mais a floatutilise moins de bits (donc plus petits et moins précis) que a double.


3

C'est une chose C - les littéraux à virgule flottante sont double précision (double) par défaut. L'ajout d'un suffixe f les rend en simple précision (float).

Vous pouvez utiliser ints pour spécifier les valeurs ici et dans ce cas cela ne fera aucune différence, mais utiliser le type correct est une bonne habitude à prendre - la cohérence est une bonne chose en général, et si vous devez modifier ces valeurs plus tard, vous Je saurai à première vue de quel type ils sont.


2

De C. Cela signifie float littéral constant. Vous pouvez omettre à la fois "f" et ".0" et utiliser ints dans votre exemple en raison de la conversion implicite d'entiers en floats.


1

Il est presque certainement de C et reflète le désir d'utiliser un type «flottant» plutôt qu'un type «double». Il est similaire aux suffixes tels que L sur les nombres pour indiquer qu'ils sont des entiers longs. Vous pouvez simplement utiliser des entiers et le compilateur effectuera une conversion automatique selon les besoins (pour ce scénario spécifique).


0

Il indique généralement au compilateur que la valeur est a float, c'est-à-dire un entier à virgule flottante. Cela signifie qu'il peut stocker des entiers, des valeurs décimales et des exponentielles, par exemple 1, 0.4ou 1.2e+22.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.