2009-07-02 14 views

Respuesta

88

Si quiere saber la verdadera respuesta, debe leer What Every Computer Scientist Should Know About Floating-Point Arithmetic.

En resumen, a pesar de double permite una mayor precisión en su representación, para ciertos cálculos que produciría errores más grandes. La opción "correcta" es: utilice tanta precisión como necesite pero no más y elija el algoritmo correcto.

Muchos compiladores realizan cálculos de coma flotante extendidos en modo "no estricto" de todos modos (es decir, utilizan un tipo de punto flotante más amplio disponible en hardware, p. Ej. 80 bits y 128 bits flotantes), esto también debe tenerse en cuenta . En la práctica, puede casi no ver ninguna diferencia en la velocidad - son nativos del hardware de todos modos.

+8

Sí. Con las CPUs modernas captando trozos de memoria cada vez más grandes, unidades de procesamiento numérico en paralelo y arquitecturas segmentadas, el problema de velocidad realmente no es un problema. Si se trata de grandes cantidades de números, quizás la diferencia de * tamaño * entre un flotador de 4 bytes y un doble de 8 bytes * podría * hacer una diferencia en la huella de memoria. – lavinio

+5

Pozo SSE (o cualquier unidad de punto flotante vertor) podrá procesar el doble de fracasos en precisión simple en comparación con la precisión doble. Si solo hace punto flotante x87 (o cualquier escalar), entonces probablemente no importe. –

+1

@Greg Rogers: los compiladores no son tan inteligentes en este momento. A menos que esté escribiendo ensamblado en bruto, no tiene grandes diferencias. Y sí, esto puede cambiar a medida que el compilador evoluciona. –

0

double tiene una mayor precisión, mientras que los flotadores ocupan menos memoria y son más rápidos. En general, debe usar flotador a menos que tenga un caso en el que no sea lo suficientemente preciso.

+3

En las computadoras modernas típicas, el doble es solo tan rápido como flotar. –

6

Personalmente voy por el doble todo el tiempo hasta que veo algunos cuellos de botella. Luego considero pasar a flotar u optimizar otra parte

3

Esto depende de cómo el compilador implementa el doble. Es legal que el doble y el flotante sean del mismo tipo (y lo es en algunos sistemas).

Dicho esto, si de hecho son diferentes, el problema principal es la precisión. Un doble tiene una precisión mucho mayor debido a su diferencia de tamaño. Si los números que está utilizando comúnmente excederán el valor de un flotante, entonces use un doble.

Varias otras personas han mencionado problemas de rendimiento. Eso sería exactamente el último en mi lista de consideraciones. La corrección debe ser su consideración # 1.

1

Creo que, independientemente de las diferencias (que, como todos señalan, las carrozas ocupan menos espacio y son en general más rápidas) ... ¿alguien alguna vez sufre problemas de rendimiento con el doble? Digo usar double ... y si luego decides "wow, esto es realmente lento" ... encuentra tu cuello de botella de rendimiento (que probablemente no sea el hecho de que utilizaste el doble). ENTONCES, si todavía es demasiado lento para ti, mira donde puedes sacrificar algo de precisión y usa flotación.

0

Depende altamente en la CPU las compensaciones más obvias son entre precisión y memoria. Con GB de RAM, la memoria no es un gran problema, por lo que generalmente es mejor usar double s.

En cuanto al rendimiento, depende en gran medida de la CPU.float s generalmente obtendrá un mejor rendimiento que double s en una máquina de 32 bits. En 64 bit, double s a veces son más rápidos, ya que es (normalmente) el tamaño nativo. Aún así, lo que importará mucho más que su elección de tipos de datos es si puede aprovechar las instrucciones SIMD en su procesador o no.

11

El doble es más preciso pero está codificado en 8 bytes. Float tiene solo 4 bytes, por lo que tiene menos espacio y menos precisión.

Debe tener mucho cuidado si tiene doble y flotante en su aplicación. Tuve un error debido a eso en el pasado. Una parte del código usaba flotante mientras que el resto del código usaba doble. Copiar dos veces para flotar y luego flotar para duplicar puede causar un error de precisión que puede tener un gran impacto. En mi caso, era una fábrica de productos químicos ... con suerte no tuvo consecuencias dramáticas :)

¡Creo que es por este tipo de error que el cohete Ariane 6 explotó hace unos años! !

pensar cuidadosamente sobre el tipo que se utilizará para una variable

+7

+1 para mezclar podría causar el problema –

+3

Tenga en cuenta que 4/8 bytes para flotador/doble ni siquiera está garantizado, dependerá de la plataforma. Incluso podría ser del mismo tipo ... – sleske

26

Esta pregunta es imposible de contestar ya que no hay contexto de la pregunta. Aquí hay algunas cosas que pueden afectar a la elección: aplicación

  1. compilador de flotadores, dobles y dobles largos. Los estados estándar de C++:

    Existen tres tipos de punto flotante: flotante, doble y doble larga. El tipo double proporciona al menos tanta precisión como float, y el tipo double double proporciona al menos tanta precisión como el doble.

    Por lo tanto, los tres pueden tener el mismo tamaño en la memoria.

  2. Presencia de una FPU. No todas las CPU tienen FPU y, a veces, se emulan los tipos de coma flotante y, a veces, los tipos de punto flotante simplemente no son compatibles.

  3. FPU Architecture. La FPU del IA32 es de 80 bits internamente: los flotadores de 32 bit y 64 bit se expanden a 80 bit en carga y se reducen en la tienda. También hay SIMD que puede hacer cuatro flotadores de 32 bits o dos flotadores de 64 bits en paralelo. El uso de SIMD no está definido en el estándar, por lo que requeriría un compilador que realice análisis más complejos para determinar si se puede usar SIMD, o requiere el uso de funciones especiales (bibliotecas o intrínsecos). El resultado del formato interno de 80 bits es que puede obtener resultados ligeramente diferentes según la frecuencia con la que se guardan los datos en la memoria RAM (por lo tanto, se pierde precisión). Por este motivo, los compiladores no optimizan particularmente el código de coma flotante.

  4. Ancho de banda de memoria. Si un doble requiere más almacenamiento que un flotador, la lectura de los datos tardará más tiempo. Esa es la respuesta ingenua. En un IA32 moderno, todo depende de dónde provienen los datos. Si está en caché L1, la carga es insignificante siempre que los datos provengan de una sola línea de caché. Si abarca más de una línea de caché, hay una pequeña sobrecarga. Si es de L2, tarda un poco más, si está en la RAM, entonces es más largo y, por último, si está en el disco, es un gran momento. Entonces, la elección de flotación o doble es menos importante que la forma en que se usan los datos. Si desea hacer un cálculo pequeño en una gran cantidad de datos secuenciales, es preferible un tipo de datos pequeño. Hacer una gran cantidad de cálculos en un pequeño conjunto de datos le permitirá usar tipos de datos más grandes con algún efecto significativo. Si accede a los datos de forma aleatoria, la elección del tamaño de los datos no es importante: los datos se cargan en páginas/líneas de caché. Por lo tanto, incluso si solo quiere un byte de la RAM, podría obtener 32 bytes transferidos (esto depende mucho de la arquitectura del sistema).Además de todo esto, la CPU/FPU podría ser súper escalar (también conocido como "pipeline"). Entonces, aunque una carga puede tomar varios ciclos, la CPU/FPU podría estar ocupada haciendo otra cosa (una multiplicación, por ejemplo) que oculta el tiempo de carga en un grado.

  5. La norma no impone ningún formato particular para valores de coma flotante.

Si tiene una especificación, eso lo guiará a la elección óptima. De lo contrario, depende de la experiencia de qué usar.

26

A menos que tenga alguna razón específica para hacerlo, use doble.

Quizás sorprendentemente, es el tipo flotante "doble" y no flotante en C (y C++). Las funciones matemáticas estándar como sin y log toman dobles como argumentos y devuelven dobles. Un literal de punto flotante normal, como cuando escribe 3.14 en su programa, tiene el tipo double. No flotar

En las computadoras modernas típicas, los dobles pueden ser tan rápidos como los flotadores, o incluso más rápidos, por lo que el rendimiento generalmente no es un factor a considerar, incluso para cálculos grandes. (Y esos tendrían que ser grandes cálculos, o el rendimiento ni siquiera debería entrar en su mente. Mi computadora de escritorio i7 puede hacer seis mil millones de multiplicaciones de dobles en un segundo.)