«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);
typeoneerror
la source

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.

Frank Shearar
la source
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.

Epatel
la source
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. */
Potatoswatter
la source
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
NickLH
la source
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.

Hans Passant
la source
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.

Yuri
la source
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.

Paul R
la source
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.

Chat sauvage
la source
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).

tyranide
la source
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.

Polynôme
la source