Puedo nombrar tres ventajas de usar double
(o float
) en lugar de decimal
:
- Utiliza menos memoria.
- Más rápido porque las operaciones matemáticas de coma flotante son compatibles de forma nativa con los procesadores.
- Puede representar un mayor rango de números.
Pero estas ventajas parecen aplicarse solo a operaciones de cálculo intensivo, como las que se encuentran en el software de modelado. Por supuesto, los dobles no deben usarse cuando se requiere precisión, como los cálculos financieros. Entonces, ¿hay alguna razón práctica para elegir double
(o float
) en lugar de decimal
en aplicaciones "normales"?
Editado para agregar: Gracias por todas las excelentes respuestas, aprendí de ellas.
Una pregunta más: algunas personas señalaron que los dobles pueden representar con mayor precisión los números reales. Cuando se declara, pensaría que generalmente también los representan con mayor precisión. Pero, ¿es una afirmación verdadera que la precisión puede disminuir (a veces significativamente) cuando se realizan operaciones de coma flotante?
Respuestas:
Creo que ha resumido las ventajas bastante bien. Sin embargo, te estás perdiendo un punto. El
decimal
tipo solo es más preciso para representar números de base 10 (por ejemplo, los utilizados en los cálculos de moneda / financieros). En general, eldouble
tipo ofrecerá al menos la misma precisión (alguien me corrige si me equivoco) y definitivamente una mayor velocidad para números reales arbitrarios. La conclusión simple es: al considerar cuál usar, siempre use adouble
menos que necesite labase 10
precisión quedecimal
ofrece.Editar:
Con respecto a su pregunta adicional sobre la disminución en la precisión de los números de punto flotante después de las operaciones, este es un problema un poco más sutil. De hecho, la precisión (uso el término indistintamente para precisión aquí) disminuirá constantemente después de realizar cada operación. Esto se debe a dos razones:
En todos los casos, si desea comparar dos números de punto flotante que en teoría deberían ser equivalentes (pero se llegó a utilizar diferentes cálculos), debe permitir un cierto grado de tolerancia (cuánto varía, pero generalmente es muy pequeño) .
Para obtener una descripción más detallada de los casos particulares en los que se pueden introducir errores en las precisiones, consulte la sección Precisión del artículo de Wikipedia . Finalmente, si desea una discusión seria y profunda (y matemática) sobre los números / operaciones de punto flotante a nivel de máquina, intente leer el artículo citado a menudo Lo que todo informático debe saber sobre la aritmética de punto flotante .
fuente
double
. Las computadoras modernas seguirán imprimiendo el valor correcto, pero solo porque "adivinen" el resultado, no porque realmente se exprese correctamente.Decimal
tipo tiene 93 bits de precisión en la mantisa, en comparación con aproximadamente 52 paradouble
. Sin embargo, desearía que Microsoft admitiera el formato IEEE de 80 bits, incluso si tuviera que rellenarse a 16 bytes; hubiera permitido un rango mayor que ,double
oDecimal
una velocidad mucho mejor queDecimal
, soporte para operaciones trascendentales (por ejemplo, sin (x), log (x), etc.), y una precisión que, si bien no es tan buena comoDecimal
sería mucho mejor quedouble
.Parece acertado con los beneficios de usar un tipo de punto flotante. Tiendo a diseñar para decimales en todos los casos, y confío en un generador de perfiles para que me haga saber si las operaciones en decimales están causando cuellos de botella o ralentizaciones. En esos casos, haré "down cast" para duplicar o flotar, pero solo lo haré internamente, y trataré cuidadosamente de manejar la pérdida de precisión limitando el número de dígitos significativos en la operación matemática que se realiza.
En general, si su valor es transitorio (no reutilizado), puede usar un tipo de coma flotante. El verdadero problema con los tipos de coma flotante son los siguientes tres escenarios.
123456789.1 * .000000000000000987654321
)EDITAR
De acuerdo con la documentación de referencia sobre decimales de C # :
Entonces, para aclarar mi declaración anterior:
Solo he trabajado en industrias donde los decimales son favorables. Si está trabajando en motores de gráficos o gráficos, probablemente sea mucho más beneficioso diseñar para un tipo de coma flotante (flotante o doble).
El decimal no es infinitamente preciso (es imposible representar una precisión infinita para no integral en un tipo de datos primitivo), pero es mucho más preciso que el doble:
EDITAR 2
En respuesta al comentario de Konrad Rudolph , el ítem # 1 (arriba) es definitivamente correcto. La agregación de la imprecisión se compone de hecho. Consulte el siguiente código para ver un ejemplo:
Esto genera lo siguiente:
Como puede ver, a pesar de que estamos agregando desde la misma fuente constante, los resultados del doble son menos precisos (aunque probablemente se redondearán correctamente), y el flotador es mucho menos preciso, hasta el punto en que se ha reducido a solo Dos dígitos significativos.
fuente
Single: 667660.400000000000
mientras que el valor decimal rindióDecimal: 666666.7000000000
. El valor flotante es un poco menos de mil sobre el valor correcto.Use decimal para valores de base 10, por ejemplo, cálculos financieros, como otros han sugerido.
Pero doble es generalmente más preciso para valores calculados arbitrarios.
Por ejemplo, si desea calcular el peso de cada línea en una cartera, use el doble ya que el resultado casi sumará hasta el 100%.
En el siguiente ejemplo, doubleResult está más cerca de 1 que decimalResult:
Así que de nuevo tomando el ejemplo de una cartera:
El valor de mercado de cada línea de la cartera es un valor monetario y probablemente se representaría mejor como decimal.
El peso de cada línea en la cartera (= Valor de mercado / SUM (Valor de mercado)) generalmente se representa mejor como doble.
fuente
Usa un doble o un flotador cuando no necesites precisión, por ejemplo, en un juego de plataformas que escribí, usé un flotador para almacenar las velocidades de los jugadores. Obviamente no necesito una súper precisión aquí porque eventualmente redondeo a un Int para dibujar en la pantalla.
fuente
En algunas Contabilidades, considere la posibilidad de utilizar tipos integrales en su lugar o en conjunto. Por ejemplo, supongamos que las reglas bajo las cuales opera requieren que cada resultado de cálculo se transfiera con al menos 6 decimales y el resultado final se redondeará al centavo más cercano.
Un cálculo de 1/6 de $ 100 rinde $ 16.66666666666666 ..., por lo que el valor realizado en una hoja de trabajo será de $ 16.666667. Tanto el doble como el decimal deberían dar ese resultado con precisión a 6 decimales. Sin embargo, podemos evitar cualquier error acumulativo llevando el resultado hacia adelante como un número entero 16666667. Cada cálculo posterior puede hacerse con la misma precisión y llevarse adelante de manera similar. Continuando con el ejemplo, calculo el impuesto a las ventas de Texas sobre esa cantidad (16666667 * .0825 = 1375000). Sumando los dos (es una hoja de trabajo corta) 1666667 + 1375000 = 18041667. Mover el punto decimal de nuevo nos da 18.041667, o $ 18.04.
Si bien este breve ejemplo no arrojaría un error acumulativo usando doble o decimal, es bastante fácil mostrar casos en los que simplemente calcular el doble o decimal y continuar acumularía un error significativo. Si las reglas bajo las cuales opera requieren un número limitado de decimales, almacenar cada valor como un número entero multiplicando por 10 ^ (número requerido de lugar decimal) y luego dividiendo por 10 ^ (número requerido de lugares decimales) para obtener el valor real El valor evitará cualquier error acumulativo.
En situaciones donde no se producen fracciones de centavos (por ejemplo, una máquina expendedora), no hay ninguna razón para usar tipos no integrales. Simplemente piense en ello como contar centavos, no dólares. He visto un código donde cada cálculo involucraba solo centavos enteros, ¡pero el uso de doble condujo a errores! Entero solo las matemáticas eliminaron el problema. Entonces, mi respuesta no convencional es, cuando sea posible, renunciar al doble y al decimal.
fuente
Si necesita intercalar binarios con otros lenguajes o plataformas, es posible que necesite usar float o double, que están estandarizados.
fuente
Nota: esta publicación se basa en la información de las capacidades del tipo decimal de http://csharpindepth.com/Articles/General/Decimal.aspx y mi propia interpretación de lo que eso significa. Asumiré que Double es normal IEEE doble precisión.
Nota 2: el más pequeño y el más grande en esta publicación se refieren a la magnitud del número.
Pros de "decimal".
Contras de decimal
Mi opinión es que debe usar el valor "decimal" por defecto para el trabajo con dinero y otros casos en los que hacer coincidir exactamente el cálculo humano es importante y que debe usar el doble como opción predeterminada el resto del tiempo.
fuente
Depende de para qué lo necesites.
Debido a que float y double son tipos de datos binarios, tiene algunas dificultades y errores en el número de rondas, por lo que double redondea 0.1 a 0.100000001490116, double también redondea 1/3 a 0.33333334326441. En pocas palabras, no todos los números reales tienen una representación precisa en tipos dobles
Afortunadamente, C # también admite la llamada aritmética decimal de coma flotante, donde los números se representan a través del sistema numérico decimal en lugar del sistema binario. Por lo tanto, la aritmética decimal de coma flotante no pierde precisión al almacenar y procesar números de coma flotante. Esto lo hace inmensamente adecuado para cálculos donde se necesita un alto nivel de precisión.
fuente
Use puntos flotantes si valora el rendimiento sobre la corrección.
fuente
Elija el tipo en función de su aplicación. Si necesita precisión como en el análisis financiero, ha respondido su pregunta. Pero si su solicitud puede resolverse con una estimación, está bien con el doble.
¿Su aplicación necesita un cálculo rápido o tendrá todo el tiempo del mundo para darle una respuesta? Realmente depende del tipo de aplicación.
Gráfico hambriento? flotar o doble es suficiente. Análisis de datos financieros, ¿meteorito golpeando un planeta tipo de precisión? Esos necesitarían un poco de precisión :)
fuente
El decimal tiene bytes más anchos, el doble es compatible de forma nativa con la CPU. El decimal es base 10, por lo que se produce una conversión de decimal a doble mientras se calcula un decimal.
Tenga en cuenta que .NET CLR solo admite Math.Pow (doble, doble). Decimal no es compatible.
.NET Framework 4
fuente
Un valor doble se serializará a notación científica por defecto si esa notación es más corta que la visualización decimal. (por ejemplo, .00000003 será 3e-8) Los valores decimales nunca se serializarán en notación científica. Cuando se serializa para el consumo de una parte externa, esto puede ser una consideración.
fuente