"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);

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.


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.


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

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

¿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.


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.


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.


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.


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).


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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.