"F" después del número

102

¿Qué findican después de los números? ¿Es esto de C o de Objective-C? ¿Hay alguna diferencia en no sumar esto a un número constante?

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

¿Puedes explicar por qué no escribiría simplemente:

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

Respuestas:

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

utiliza constantes flotantes. (La constante 0.0 generalmente declara un doble en Objective-C; poner una f al final, 0.0f, declara la constante como un flotante (de 32 bits)).

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

utiliza ints que se convertirán automáticamente en flotantes.

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

Frank Shearar
fuente
24
En teoría, es posible que el compilador no sea lo suficientemente inteligente como para convertirlos a flotantes 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 casi no es importante, siempre es mejor especificar correctamente f si es necesario: en una expresión, una constante sin el especificador correcto puede forzar que toda la expresión se convierta en doble, y si está en un bucle cerrado, el rendimiento puede verse afectado. perceptible.
Matteo Italia
60

En caso de duda, compruebe la salida del ensamblador. Por ejemplo, escriba un pequeño fragmento mínimo, como este

#import <Cocoa/Cocoa.h>

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

Luego compílelo en ensamblador con la -Sopción.

gcc -S test.m

Guarde la salida del ensamblador en el test.sarchivo y elimínela .0fde las constantes y repita el comando de compilación. Luego haz una diffde las nuevas test.sy anteriores. Piense que eso 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 del día, uno debería saber cómo verificar las teorías.

epatel
fuente
11
La salida resultó ser idéntica para mí, incluso sin ninguna -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 también eran idénticos.
Nick
43

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. */
Potatoswatter
fuente
26

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

3.0f -> float
3.0 -> double
3 -> integer
NickLH
fuente
¿Esta convención es parte del estándar C ++ o se encuentra en el compilador?
jxramos
1
Por lo que puedo decir, es parte del estándar (alguien me corrija si me equivoco). La referencia más rápida que pude encontrar es open-std.org/jtc1/sc22/open/n2356/lex.html#lex.fcon , pero probablemente haya más referencias actualizadas si desea buscarlas.
NickLH
5

Un literal de punto flotante en su código fuente se analiza como un doble. Asignarlo a una variable de tipo float perderá precisión. Mucha precisión, estás desperdiciando 7 dígitos significativos. El sufijo "f" te permite decirle al compilador: "Sé lo que estoy haciendo, esto es intencional. No me molestes".

Las probabilidades de producir un error no son tan pequeñas por cierto. Muchos programas se han hundido en una comparación de punto flotante mal concebida o suponiendo que 0,1 es exactamente representable.

Hans Passant
fuente
4

El del fque estás hablando probablemente esté destinado a decirle al compilador que está trabajando con un flotador. Cuando omite el f, generalmente se traduce a un doble.

Ambos son números de coma flotante, pero a floatusa menos bits (por lo tanto, más pequeños y menos precisos) que a double.

Yuri
fuente
3

Es una cosa de C: los literales de punto flotante son de doble precisión (doble) de forma predeterminada. Agregar un sufijo f hace que sean de precisión simple (flotante).

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: la coherencia es algo bueno en general, y si necesita cambiar estos valores más adelante, Sabrás a primera vista de qué tipo son.

Paul R
fuente
2

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

Gato montés
fuente
1

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

tiránido
fuente
0

Por lo general, le dice al compilador que el valor es a float, es decir, un entero de punto flotante. Esto significa que puede almacenar números enteros, valores decimales y exponenciales, por ejemplo 1, 0.4o 1.2e+22.

Polinomio
fuente