2010-08-02 9 views

Respuesta

16

Los valores científicos tienden a ser valores "naturales" (longitud, masa, tiempo, etc.) donde hay un grado natural de imprecisión para empezar, pero donde es posible que desee números muy, muy grandes o muy, muy pequeños. Para estos valores, generalmente es una buena idea double. Es rápido (con soporte de hardware en casi todas partes), escala de arriba a abajo a valores enormes/pequeños, y generalmente funciona bien si no le preocupan los valores exactos de decimal.

decimal es un buen tipo para números "artificiales" donde hay un valor exacto, casi siempre representado naturalmente como un decimal - el ejemplo canónico para esto es la moneda. Sin embargo, es dos veces más caro que double en términos de almacenamiento (8 bytes por valor en lugar de 4), tiene un rango menor (debido a un rango de exponente más limitado) y es significativamente más lento debido a la falta de soporte de hardware.

Personalmente, solo usaría float si el almacenamiento fuera un problema. Es sorprendente cuán rápido pueden acumularse las imprecisiones cuando solo tiene alrededor de 7 lugares decimales significativos.

En última instancia, como sugiere el comentario de "los osos te comerán", depende de qué valores estés hablando y, por supuesto, qué piensas hacer con ellos. Sin más información, sospecho que double es un buen punto de partida, pero en realidad debería tomar la decisión en función de la situación individual.

+1

Me gusta la distinción "natural" vs. "artificial". –

5

Double parece ser el tipo de datos más confiable para tales operaciones. Incluso WPF lo usa extensivamente.

8

Bueno, por supuesto el término "cálculo científico" es un poco vago, pero en general, es double.

float es principalmente compatible con bibliotecas que esperan números de punto flotante de 32 bits. La ejecución de las operaciones float y double (como la suma) es exactamente la misma, por lo que el código nuevo siempre debe usar double porque tiene una mayor precisión.

Sin embargo, el x86 JITter nunca insertará funciones que tomen o devuelvan un float, por lo que el uso de float en métodos podría ser más lento. Una vez más, esto es para la compatibilidad: si estuviera en línea, el motor de ejecución omitiría un paso de conversión que reduce su precisión, y por lo tanto el JITter podría cambiar inadvertidamente el resultado de algunos cálculos si fuera a alinear tales funciones.

Finalmente, también está decimal. Úselo cuando sea importante tener un cierto número de decimales. El caso de uso estereotípico es operaciones monetarias, pero, por supuesto, admite más de dos decimales, en realidad es un dato de 80 bits.

Si incluso la precisión de 64-bit double no es suficiente, considere usar una biblioteca externa para números de precisión arbitrarios, pero por supuesto solo lo necesitará si su caso de uso científico específico lo requiere específicamente.

+2

Buenos puntos sobre el rendimiento. –

+0

¿Fuente en el reclamo en línea? Hubo un error que se solucionó en 3.5 SP1 que no permitía al JIT alinear funciones que tomaban parámetros de tipo de valor, pero no puedo pensar en ningún otro problema. – JulianR

+0

Ya no puedo encontrar la fuente, pero mencioné el problema. La pila de evaluación de CLR solo usa valores de 64 bits para números de coma flotante. Cada vez que se pasa un flotante de 32 bits a un método, o un método devuelve un flotante de 32 bits, el valor de la pila de evaluación se convierte específicamente en un flotante de 32 bits para preservar su falta de precisión. – Timwi

2

Tenga en cuenta que los decimales son mucho más caros de usar que los flotadores/dobles (además de lo que Jon Skeet y Timwi escribieron).

0

Recomendaría el doble a menos que necesite el valor para ser exacto; decimal es para cálculos financieros que necesitan esta exactitud.Los cálculos científicos toleran pequeños errores porque no se puede medir exactamente 1 metro de todos modos. Float solo ayuda si el almacenamiento es un problema (es decir, enormes matrices).

Cuestiones relacionadas