2010-03-06 12 views
91

No puedo encontrar esto en los documentos de Apple así que: ¿qué indica la "f" después de los números aquí? ¿Esto es de C o Objective-C? ¿Hay alguna diferencia en no agregar esto a un número constante?"f" después del número/flotante en Objective-C/C

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

Puede explicar por qué no me acaba de escribir:

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

Respuesta

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

usa constantes de flotación. (La constante de 0,0 por lo general declara un doble en Objective-C, poniendo f en el extremo - 0.0f - declara la constante como un flotador (32 bits).)

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

utiliza enteros que se convierten automáticamente para flotar.

En este caso, no hay diferencia (práctica) entre los dos.

+24

Teóricamente, el compilador puede no ser lo suficientemente inteligente como para convertirlos a flotación en tiempo de compilación, y ralentizaría la ejecución con cuatro conversiones int-> float (que se encuentran entre las conversiones más lentas). Aunque en este caso es casi irrelevante, siempre es mejor especificar f correctamente si es necesario: en una expresión, una constante sin el especificador correcto puede obligar a que toda la expresión se convierta en doble, y si está en un ciclo cerrado, el rendimiento puede ser perceptible. –

2

Es una cosa C - literales de coma flotante de doble precisión son (doble) de forma predeterminada. Agregar un sufijo f los hace una sola precisión (float).

Puede usar ints para especificar los valores aquí y en este caso no hará ninguna diferencia, pero usar el tipo correcto es un buen hábito para entrar - la consistencia es algo bueno en general, y si necesita cambiar estos valores más adelante sabrá a primera vista de qué tipo son.

1

Es casi seguro que proviene de C y refleja el deseo de utilizar un tipo 'flotante' en lugar de 'doble'. Es similar a los sufijos como L en los números para indicar que son enteros largos. Solo puede usar enteros y el compilador se convertirá automáticamente según corresponda (para este escenario específico).

2

De C. Significa la constante literal de flotación. Puede omitir tanto "f" como ".0" y utilizar ints en su ejemplo debido a la conversión implícita de las entradas a flotantes.

41

A veces hay una diferencia.

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. */ 
4

Un literal de coma flotante en el código fuente se analiza como un doble. Asignarlo a una variable que es de tipo float perderá precisión. Con mucha precisión, estás desperdiciando 7 dígitos significativos. El postfijo "f" le dice al compilador: "Sé lo que estoy haciendo, esto es intencional. No me molestes al respecto".

Las probabilidades de producir un error no son tan pequeñas por cierto. Muchos programas se han ahogado en una comparación de coma flotante mal concebida o asumiendo que 0.1 es exactamente representable.

49

En caso de duda, compruebe la salida del ensamblador. Por ejemplo escribir un pequeño fragmento de código, es decir, como mínimo este

#import <Cocoa/Cocoa.h> 

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

A continuación, compile a ensamblador con la opción -S.

gcc -S test.m 

guardar la salida de ensamblador en el archivo test.s y retire .0f partir de las constantes y repita el comando de compilación. Luego haga un diff del nuevo test.s y el anterior. Piensa que debería mostrar si hay diferencias reales.Creo que muchos tienen una visión de lo que creen que hace el compilador, pero al final uno debe saber cómo verificar cualquier teoría.

+11

+1 para "verificar la salida del conjunto"! Consejo muy útil para descubrir cómo funcionan las cosas en el metal. –

+10

La salida resultó ser idéntica para mí, incluso sin '-O'. Estoy en i686-apple-darwin10-gcc-4.2.1 (GCC) – kizzx2

+2

Probé el ejemplo anterior con LLVM versión 7.0.0 (clang-700.0.65) x86_64-apple-darwin15.0.0 y los archivos .out fueron idéntico también. – Nick

0

Suele indicar al compilador que el valor es float, es decir, un entero de coma flotante. Esto significa que puede almacenar enteros, valores decimales y exponenciales, p. Ej. 1, 0.4 o 1.2e+22.

23

Le dice a la computadora que este es un número de punto flotante (supongo que usted está hablando de c/C++ aquí). Si no hay ninguna f después del número, se considera un doble o un número entero (dependiendo de si hay un decimal o no).

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

es esta convención parte del estándar de C++ o se encuentra en el compilador? – jxramos

+1

Por lo que puedo decir, es parte del estándar (alguien me corrige si estoy equivocado). La referencia más rápida que pude encontrar es http://open-std.org/jtc1/sc22/open/n2356/lex.html#lex.fcon, pero probablemente haya más referencias actualizadas si desea buscarlas. – NickLH

3

El f que estamos hablando es, probablemente, la intención de decirle al compilador que está trabajando con un flotador. Cuando omite el f, por lo general se traduce a un doble.

Ambos son números flotantes, pero un float utiliza menos bits (por lo tanto, más pequeños y menos precisos) que un double.