¿Cuándo usas flotador y cuándo usas doble

194

Con frecuencia, en mi experiencia en programación, necesito tomar una decisión si debo usar flotante o doble para mis números reales. A veces voy a flotar, a veces voy por el doble, pero realmente esto se siente más subjetivo. Si me confrontaran para defender mi decisión, probablemente no daría buenas razones.

¿Cuándo usas flotador y cuándo usas doble? ¿Siempre usas el doble, solo cuando existen limitaciones de memoria vas a flotar? ¿O usa siempre flotante a menos que el requisito de precisión requiera que use doble? ¿Existen algunas diferencias sustanciales con respecto a la complejidad computacional de la aritmética básica entre flotante y doble? ¿Cuáles son las ventajas y desventajas de usar flotador o doble? ¿Y has usado incluso el doble largo?

Jakub Zaverka
fuente
28
En muchos casos, no desea utilizar ninguno, sino un tipo decimal flotante o de punto fijo. Los tipos de punto flotante binario no pueden representar la mayoría de los decimales exactamente.
CodesInChaos
3
Relacionado con ¿Qué causa los errores de redondeo de coma flotante? . @CodesInChaos mi respuesta allí sugiere recursos para ayudarlo a tomar esa determinación, no existe una solución única para todos .
Mark Booth
Muy buena respuesta encontrada en: Desbordamiento de pila
Haris
55
¿Qué quieres decir exactamente con "decimales"? Si necesita representar valores como 0.01 exactamente (por ejemplo, por dinero), entonces el punto flotante (binario) no es la respuesta. Si simplemente quiere decir números no enteros, entonces el punto flotante probablemente esté bien, pero entonces "decimales" no es la mejor palabra para describir lo que necesita.
Keith Thompson
1
No siempre tienes otra opción. Por ejemplo, en la plataforma Arduino, tanto double como float equivalen a float. Necesitas encontrar una biblioteca de complementos para manejar dobles reales.
kiwiron

Respuestas:

187

La opción predeterminada para un tipo de punto flotante debería ser double. Este es también el tipo que se obtiene con los literales de punto flotante sin un sufijo o (en C) funciones estándar que operan sobre números de punto flotante (por ejemplo exp, sin, etc.).

float solo debe usarse si necesita operar con muchos números de punto flotante (piense en el orden de miles o más) y el análisis del algoritmo ha demostrado que el rango y la precisión reducidos no representan un problema.

long doublepuede usarse si necesita más alcance o precisión que double, y si lo proporciona en su plataforma de destino.

En resumen, floaty long doubledebe reservarse para el uso de los especialistas, con el uso doublede "todos los días".

Bart van Ingen Schenau
fuente
10
Probablemente no consideraría flotante para unos pocos miles de valores a menos que hubiera un problema de rendimiento relacionado con el almacenamiento en caché de punto flotante y la transferencia de datos. Por lo general, hay un costo sustancial para hacer el análisis para mostrar que el flotador es lo suficientemente preciso.
Patricia Shanahan
44
Como anexo, si necesita compatibilidad con otros sistemas, puede ser ventajoso usar los mismos tipos de datos.
zzzzBov
15
Usaría flotadores para millones de números, no 1000. Además, algunas GPU funcionan mejor con flotadores, en ese caso especializado, utilice flotadores. De lo contrario, como dices, usa dobles.
user949300
44
@PatriciaShanahan - 'problema de rendimiento relacionado con ...' Un buen ejemplo es si está planeando usar SSE2 o instrucciones de vectores similares, puede hacer 4 operaciones / vector en flotante (vs 2 por doble) que pueden proporcionar una mejora significativa de la velocidad ( la mitad de las operaciones y la mitad de los datos para leer y escribir). Esto puede reducir significativamente el umbral en el que el uso de flotadores se vuelve atractivo, y vale la pena resolver los problemas numéricos.
greggo
12
Respaldo esta respuesta con un consejo adicional: cuando uno está operando con valores RGB para visualización, es aceptable usarlo float(y ocasionalmente la mitad de precisión) porque ni el ojo humano, la pantalla o el sistema de color tienen tantos bits de precisión . Este consejo es aplicable para, por ejemplo, OpenGL, etc. Este consejo adicional no se aplica a las imágenes médicas, que tienen requisitos de precisión más estrictos.
rwong
42

Raramente hay causa para usar flotante en lugar de doble en el código dirigido a computadoras modernas. La precisión adicional reduce (pero no elimina) la posibilidad de errores de redondeo u otras imprecisiones que causen problemas.

Las principales razones por las que puedo pensar en usar float son:

  1. Está almacenando grandes conjuntos de números y necesita reducir el consumo de memoria de su programa.
  2. Está apuntando a un sistema que no admite de forma nativa el punto flotante de doble precisión. Hasta hace poco, muchas tarjetas gráficas solo admitían puntos flotantes de precisión simple. Estoy seguro de que hay muchos procesadores integrados y de baja potencia que también tienen soporte de coma flotante limitado.
  3. Está apuntando a hardware donde la precisión simple es más rápida que la precisión doble, y su aplicación hace un uso intensivo de la aritmética de coma flotante. En las CPU modernas de Intel, creo que todos los cálculos de coma flotante se realizan con doble precisión, por lo que no gana nada aquí.
  4. Está realizando una optimización de bajo nivel, por ejemplo, utilizando instrucciones especiales de la CPU que operan en varios números a la vez.

Entonces, básicamente, el doble es el camino a seguir a menos que tenga limitaciones de hardware o que el análisis haya demostrado que almacenar números de doble precisión está contribuyendo significativamente al uso de la memoria.

usuario611910
fuente
2
"Computadoras modernas", que significa procesadores Intel x86. Algunas de las máquinas que usaban los Antiguos proporcionaban una precisión perfectamente adecuada con el tipo de flotador básico. (El CDC 6600 usó una palabra de 60 bits, 48 ​​bits de mantisa de coma flotante normalizada, 12 bits de exponente. Eso es CASI lo que el x86 le da para doble precisión.)
John R. Strohm
@ John.R.Strohm: de acuerdo, pero los compiladores de C no existían en CDC6600. Fue Fortran IV ...
Basile Starynkevitch
Por "computadoras modernas" me refiero a cualquier procesador construido en la última década o dos, o realmente, ya que el estándar de punto flotante IEEE se implementó ampliamente. Soy perfectamente consciente de que existen arquitecturas que no son x86 y tuve esto en cuenta con mi respuesta: mencioné GPU y procesadores integrados, que generalmente no son x86.
user611910
Sin embargo, eso simplemente no es cierto. SSE2 puede manipular 4 flotadores o 2 dobles en una operación, AVX puede manipular 8 flotadores o 4 dobles, AVX-512 puede manipular 16 flotadores u 8 dobles. Para cualquier tipo de computación de alto rendimiento, las matemáticas en flotadores deben considerarse como el doble de la velocidad de las mismas operaciones en dobles en x86.
Larry Gritz
1
Y es aún peor que eso, ya que puede colocar el doble de flotantes en la memoria caché del procesador que puede con los dobles, y la latencia de la memoria es probablemente el principal cuello de botella en muchos programas. Mantener un conjunto completo de flotadores activos en la memoria caché puede ser literalmente un orden de magnitud más rápido que usar dobles y hacer que se derramen a la RAM.
Larry Gritz
10

Úselo doublepara todos sus cálculos y variables temporales. Úselo floatcuando necesite mantener una matriz de números float[](si la precisión es suficiente), y se trata de más de decenas de miles de floatnúmeros.

Muchas / la mayoría de las funciones u operadores matemáticos convierten / devuelven double, y no desea volver a convertir los números floatpara ningún paso intermedio.

Por ejemplo, si tiene una entrada de 100,000 números de un archivo o una secuencia y necesita ordenarlos, coloque los números en a float[].

Fai Ng
fuente
5

Algunas plataformas (ARM Cortex-M2, Cortex-M4, etc.) no admiten el doble (siempre se puede verificar en el manual de referencia de su procesador. Si no hay advertencias o errores de compilación, no significa que el código sea óptimo. doble puede ser emulado). Es por eso que es posible que deba apegarse a int o float .

Si ese no es el caso, usaría el doble .

Puede consultar el famoso artículo de D. Goldberg ("Lo que todo informático debe saber sobre la aritmética de coma flotante"). Debería pensarlo dos veces antes de usar la aritmética de punto flotante. Existe una gran posibilidad de que no sean necesarios en su situación particular.

http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf

Staroselskii
fuente
3
Esta pregunta ya estaba bastante bien respondida hace un año ... pero, en cualquier caso, diría que cada vez que use doble en plataformas con aceleración FPU de doble precisión, debería usarla en cualquier otro, incluso si eso significa dejando que el compilador lo emule en lugar de aprovechar una FPU con solo punto flotante (tenga en cuenta que las FPU tampoco son necesarias en todas las plataformas, de hecho, una arquitectura Cortex-M4 las define como una característica opcional [¿M2 era un error tipográfico?] )
Selali Adobor
La clave de esa lógica es que, si bien es cierto, uno debería estar cansado de la aritmética de coma flotante, y son muchas "peculiaridades", que definitivamente no requieren la presencia de soporte de FPU para dobles, lo que significa simplemente usar dobles en lugar de flotantes. Los flotadores son generalmente más rápidos que los dobles y requieren menos memoria (las características de la FPU varían). El volumen de uso impide que este punto tenga una optimización prematura. Al igual que el hecho, los dobles son claramente excesivos para muchas aplicaciones (tal vez incluso la mayoría). ¿Los elementos en esta página realmente necesitan tener sus posiciones y tamaños relativos calculados a 13 decimales?
Selali Adobor
2
Al incluir un enlace a una página o documento fuera del sitio, copie la información relevante o el resumen del documento en su respuesta. Los enlaces fuera del sitio tienden a desaparecer con el tiempo.
Adam Zuckerman
3

Para problemas del mundo real, el umbral de muestreo de sus datos es importante al responder esta pregunta. Del mismo modo, el ruido de fondo también es importante. Si cualquiera de los dos supera su selección de tipo de datos, no se obtendrá ningún beneficio al aumentar la precisión.

La mayoría de los muestreadores del mundo real están limitados a DAC de 24 bits. Sugerir que 32 bits de precisión en los cálculos del mundo real debe ser adecuado donde el significado es de 24 bits de precisión.

La doble precisión tiene el costo de 2x de memoria. Por lo tanto, limitar el uso de dobles sobre flotadores podría reducir drásticamente la huella de memoria / ancho de banda de las aplicaciones en ejecución.

usuario3034617
fuente
-3

La elección de qué variable usar entre flotante y doble depende de la precisión de los datos requeridos. Si se requiere que una respuesta tenga una diferencia insignificante con respecto a la respuesta real, el número de lugares decimales requeridos será mayor, por lo tanto, dictará que el doble esté en uso. Flotador cortará algunas partes de lugares decimales, reduciendo así la precisión.

David Monyancha
fuente
3
Esta respuesta no agrega nada nuevo a la pregunta y no dice nada de uso real.
Martijn Pieters
-5

Por lo general, uso el floattipo cuando no necesito mucha precisión, por ejemplo, por dinero, lo cual está mal, pero es lo que estoy acostumbrado a hacer mal.

Por otro lado, lo uso doublecuando necesito más precisión, por ejemplo, para algoritmos matemáticos complejos.

El estándar C99 dice esto:

Hay tres tipos de coma flotante: flotante, doble y doble largo. El tipo doble proporciona al menos tanta precisión como flotante, y el tipo doble largo proporciona al menos tanta precisión como el doble. El conjunto de valores del tipo float es un subconjunto del conjunto de valores del tipo double; El conjunto de valores del tipo double es un subconjunto del conjunto de valores del tipo long double.

Realmente nunca usé long double, pero no uso tanto C / C ++. Por lo general, uso lenguajes de tipo dinámico como Python, donde no tiene que preocuparse por los tipos.

Para obtener más información sobre Double vs Float , consulte esta pregunta en SO .

Addison Montgomery
fuente
25
El uso de coma flotante para cálculos serios de dinero es probablemente un error.
Bart van Ingen Schenau
17
flotador es exactamente el tipo incorrecto de dinero. Debe estar utilizando la mayor precisión posible.
ChrisF
8
@BartvanIngenSchenau El punto flotante por dinero generalmente está bien, el punto flotante binario no. Por ejemplo, .net Decimales un tipo de punto flotante y suele ser una buena opción para los cálculos de dinero.
CodesInChaos
13
@ChrisF No necesita "alta precisión" para el dinero, necesita valores exactos.
Sean McSomething
2
@SeanMcSomething - Punto justo. Sin embargo, los flotantes siguen siendo del tipo incorrecto y, dados los tipos de coma flotante disponibles en la mayoría de los idiomas, necesita "alta precisión" para obtener "valores exactos".
ChrisF