Diferencia entre decimal, flotante y doble en .NET?

¿Cuál es la diferencia entre decimal , float y double en .NET?

¿Cuándo alguien usaría uno de estos?

float y double son tipos de puntos binarios flotantes . En otras palabras, representan un número como este:

 10001.10010110011 

El número binario y la ubicación del punto binario están codificados dentro del valor.

decimal es un tipo de punto decimal flotante . En otras palabras, representan un número como este:

 12345.65789 

De nuevo, el número y la ubicación del punto decimal están codificados dentro del valor; eso es lo que hace que el decimal siga siendo un tipo de punto flotante en lugar de un tipo de punto fijo.

Lo importante a tener en cuenta es que los humanos están acostumbrados a representar números enteros en forma decimal, y esperan resultados exactos en representaciones decimales; no todos los números decimales son exactamente representables en el punto flotante binario – 0.1, por ejemplo – así que si usas un valor binario de coma flotante obtendrás una aproximación a 0.1. Igual obtendrás aproximaciones al usar un punto decimal flotante también; el resultado de dividir 1 por 3 no se puede representar exactamente, por ejemplo.

En cuanto a qué usar cuando:

  • Para valores que son “decimales naturalmente exactos”, es bueno usar decimal . Esto generalmente es adecuado para cualquier concepto inventado por humanos: los valores financieros son el ejemplo más obvio, pero también hay otros. Considere la puntuación dada a los buceadores o patinadores sobre hielo, por ejemplo.

  • Para valores que son más artefactos de la naturaleza que en realidad no se pueden medir exactamente de todos modos, float / double son más apropiados. Por ejemplo, los datos científicos generalmente se representarían de esta forma. Aquí, los valores originales no serán “decimales” para empezar, por lo que no es importante que los resultados esperados mantengan la “precisión decimal”. Los tipos de puntos binarios flotantes son mucho más rápidos de trabajar que los decimales.

La precisión es la principal diferencia.

Flotador : 7 dígitos (32 bits)

Doble -15-16 dígitos (64 bit)

Decimal -28-29 dígitos significativos (128 bit)

Los decimales tienen una precisión mucho mayor y se usan generalmente en aplicaciones financieras que requieren un alto grado de precisión. Los decimales son mucho más lentos (hasta 20 veces en algunas pruebas) que un doble / flotante.

Decimales y Flotadores / Dobles no se pueden comparar sin un yeso, mientras que los Flotadores y Dobles sí pueden. Los decimales también permiten la encoding o los ceros finales.

 float flt = 1F/3; double dbl = 1D/3; decimal dcm = 1M/3; Console.WriteLine("float: {0} double: {1} decimal: {2}", flt, dbl, dcm); 

Resultado:

 float: 0.3333333 double: 0.333333333333333 decimal: 0.3333333333333333333333333333 

La estructura Decimal está estrictamente orientada a cálculos financieros que requieren precisión, que son relativamente intolerantes al redondeo. Los decimales no son adecuados para aplicaciones científicas, sin embargo, por varias razones:

  • Una cierta pérdida de precisión es aceptable en muchos cálculos científicos debido a los límites prácticos del problema físico o artefacto que se mide. La pérdida de precisión no es aceptable en las finanzas.
  • El decimal es mucho (mucho) más lento que flotante y doble para la mayoría de las operaciones, principalmente porque las operaciones de punto flotante se realizan en binario, mientras que las decimales se hacen en base 10 (es decir, flotantes y dobles manejadas por el hardware FPU, como MMX / SSE , mientras que los decimales se calculan en software).
  • El decimal tiene un rango de valores inaceptablemente menor que el doble, a pesar de que admite más dígitos de precisión. Por lo tanto, Decimal no se puede usar para representar muchos valores científicos.

float 7 dígitos de precisión

double tiene cerca de 15 dígitos de precisión

decimal tiene alrededor de 28 dígitos de precisión

Si necesita una mayor precisión, use el doble en lugar de flotar. En las CPU modernas, ambos tipos de datos tienen casi el mismo rendimiento. El único beneficio de usar flotador es que ocupan menos espacio. Prácticamente importa solo si tienes muchos de ellos.

Encontré que esto es interesante. Lo que todo informático debería saber sobre la aritmética de coma flotante

Nadie ha mencionado eso

En las configuraciones predeterminadas, Floats (System.Single) y double (System.Double) nunca usarán la verificación de desbordamiento, mientras que Decimal (System.Decimal) siempre usará la verificación de desbordamiento.

quiero decir

 decimal myNumber = decimal.MaxValue; myNumber += 1; 

lanza OverflowException .

Pero estos no:

 float myNumber = float.MaxValue; myNumber += 1; 

&

 double myNumber = double.MaxValue; myNumber += 1; 

No voy a reiterar toneladas de información buena (y mala) ya respondida en otras respuestas y comentarios, pero responderé a su pregunta de seguimiento con un consejo:

¿Cuándo alguien usaría uno de estos?

Use decimal para los valores contados

Use flotante / doble para valores medidos

Algunos ejemplos:

  • dinero (¿contamos dinero o medimos dinero?)

  • distancia (¿contamos la distancia o medimos la distancia? *)

  • puntajes (¿contamos puntajes o medimos puntajes?)

Siempre contamos dinero y nunca debemos medirlo. Usualmente medimos la distancia. A menudo contamos puntajes.

* En algunos casos, lo que yo llamaría distancia nominal , podemos querer ‘contar’ la distancia. Por ejemplo, tal vez estamos tratando con señales de países que muestran las distancias a las ciudades, y sabemos que esas distancias nunca tienen más de un dígito decimal (xxx.x km).

  1. El doble y el flotante se pueden dividir por cero entero sin una excepción tanto en la comstackción como en el tiempo de ejecución.
  2. El decimal no se puede dividir por entero cero. La comstackción siempre fallará si haces eso.

Los tipos de variable Decimal, Doble y Float son diferentes en la forma en que almacenan los valores. La precisión es la principal diferencia donde float es un tipo de datos de coma flotante de precisión simple (32 bits), double es un tipo de datos de coma flotante de doble precisión (64 bits) y decimal es un tipo de datos de coma flotante de 128 bits.

Flotante: 32 bits (7 dígitos)

Doble – 64 bit (15-16 dígitos)

Decimal – 128 bit (28-29 dígitos significativos)

La diferencia principal es que los flotantes y los dobles son tipos de coma flotante binarios y un decimal almacenará el valor como un tipo de punto decimal flotante. Por lo tanto, los decimales tienen una precisión mucho mayor y se usan generalmente en aplicaciones de cálculo monetario (financiero) o científico que requieren un alto grado de precisión. Pero en términos de rendimiento, los decimales son más lentos que los tipos dobles y flotantes.

El decimal puede representar 100% con precisión cualquier número dentro de la precisión del formato decimal, mientras que Float y Double no pueden representar con precisión todos los números, incluso los números que están dentro de sus respectivos formatos de precisión.

Decimal

En el caso de aplicaciones financieras o cálculos científicos, es mejor utilizar tipos de Decimal porque le proporciona un alto nivel de precisión y es fácil evitar los errores de redondeo.

Doble

Los tipos dobles son probablemente el tipo de datos más utilizado para valores reales, excepto el manejo de dinero.

Flotador

Se usa principalmente en bibliotecas gráficas debido a las altas demandas de potencia de procesamiento, también se usan situaciones que pueden soportar errores de redondeo.

Los enteros, como se mencionó, son números enteros. No pueden almacenar el punto en algo, como .7, .42 y .007. Si necesita almacenar números que no son números enteros, necesita un tipo diferente de variable. Puede usar el tipo doble o el tipo flotante. Establece estos tipos de variables exactamente de la misma manera: en lugar de usar la palabra int , escribe double o float . Me gusta esto:

 float myFloat; double myDouble; 

( float es la abreviatura de “punto flotante”, y solo significa un número con un punto algo en el extremo).

La diferencia entre los dos está en el tamaño de los números que pueden contener. Para float , puede tener hasta 7 dígitos en su número. Para double s, puede tener hasta 16 dígitos. Para ser más precisos, este es el tamaño oficial:

 float: 1.5 × 10^-45 to 3.4 × 10^38 double: 5.0 × 10^-324 to 1.7 × 10^308 

float es un número de 32 bits, y double es un número de 64 bits.

Haga doble clic en su nuevo botón para obtener el código. Agregue las siguientes tres líneas a su código de botón:

 double myDouble; myDouble = 0.007; MessageBox.Show(myDouble.ToString()); 

Detenga su progtwig y regrese a la ventana de encoding. Cambiar esta línea:

 myDouble = 0.007; myDouble = 12345678.1234567; 

Ejecute su progtwig y haga clic en su botón doble. El cuadro de mensaje muestra correctamente el número. Agregue otro número al final, sin embargo, y C # nuevamente se redondeará hacia arriba o hacia abajo. La moraleja es que si quieres precisión, ten cuidado con el redondeo.

Este ha sido un hilo interesante para mí, ya que hoy, acabamos de tener un pequeño error desagradable, con respecto a que el decimal tiene menos precisión que un float .

En nuestro código C #, estamos leyendo valores numéricos de una hoja de cálculo de Excel, convirtiéndolos en un decimal , y luego enviando este decimal nuevamente a un Servicio para guardarlo en una base de datos de SQL Server .

 Microsoft.Office.Interop.Excel.Range cell = … object cellValue = cell.Value2; if (cellValue != null) { decimal value = 0; Decimal.TryParse(cellValue.ToString(), out value); } 

Ahora, para casi todos nuestros valores de Excel, esto funcionó maravillosamente. Pero para algunos valores de Excel muy pequeños, el uso de decimal.TryParse perdido el valor por completo. Un tal ejemplo es

  • cellValue = 0.00006317592

  • Decimal.TryParse (cellValue.ToString (), valor de salida); // devolvería 0

La solución, extrañamente, era convertir los valores de Excel en un double primero, y luego en un decimal :

 Microsoft.Office.Interop.Excel.Range cell = … object cellValue = cell.Value2; if (cellValue != null) { double valueDouble = 0; double.TryParse(cellValue.ToString(), out valueDouble); decimal value = (decimal) valueDouble; … } 

A pesar de que el double tiene menos precisión que un decimal , esto en realidad aseguró que aún se reconocerían números pequeños. Por alguna razón, double.TryParse fue capaz de recuperar esos números pequeños, mientras que decimal.TryParse los establecería en cero.

Impar. Muy raro.

flotar ~ ± 1.5 x 10-45 a ± 3.4 x 1038 ——– 7 figuras
doble ~ ± 5.0 x 10-324 a ± 1.7 x 10308 —— 15 o 16 figuras
decimal ~ ± 1.0 x 10-28 a ± 7.9 x 1028 ——– 28 o 29 figuras

Para aplicaciones como juegos y sistemas integrados en los que la memoria y el rendimiento son críticos, el flotante suele ser el tipo de elección numérica, ya que es más rápido y la mitad del tamaño de un doble. Los enteros solían ser el arma de elección, pero el rendimiento en coma flotante ha superado el número entero en los procesadores modernos. ¡Decimal está fuera!

Los tipos de variable Decimal, Doble y Float son diferentes en la forma en que almacenan los valores. La precisión es la principal diferencia donde float es un tipo de datos de coma flotante de precisión simple (32 bits), double es un tipo de datos de coma flotante de doble precisión (64 bits) y decimal es un tipo de datos de coma flotante de 128 bits.

Flotante: 32 bits (7 dígitos)

Doble – 64 bit (15-16 dígitos)

Decimal – 128 bit (28-29 dígitos significativos)

Más sobre … la diferencia entre Decimal, Float y Double

El problema con todos estos tipos es que subsiste cierta imprecisión Y que este problema puede ocurrir con números decimales pequeños como en el siguiente ejemplo

 Dim fMean as Double = 1.18 Dim fDelta as Double = 0.08 Dim fLimit as Double = 1.1 If fMean - fDelta < fLimit Then bLower = True Else bLower = False End If 

Pregunta: ¿Qué valor contiene la variable bLower?

Respuesta: ¡En una máquina de 32 bits, bLower contiene TRUE!

Si reemplazo Double by Decimal, bLower contiene FALSE, que es la buena respuesta.

En el doble, el problema es que fMean-fDelta = 1.09999999999 que es menor que 1.1.

Precaución: creo que el mismo problema puede existir para otros números porque Decimal es solo un doble con mayor precisión y la precisión siempre tiene un límite.

De hecho, Double, Float y Decimal corresponden a BINARY decimal en COBOL!

Es lamentable que otros tipos numéricos implementados en COBOL no existan en .Net. Para aquellos que no conocen COBOL, existen en COBOL siguiendo el tipo numérico

 BINARY or COMP like float or double or decimal PACKED-DECIMAL or COMP-3 (2 digit in 1 byte) ZONED-DECIMAL (1 digit in 1 byte) 

La principal diferencia entre cada uno de estos es la precisión.

float es un número de 32-bit , double es un número de 64-bit y decimal es un número de 128-bit .

En palabras simples:

  1. Los tipos de variable Decimal, Doble y Float son diferentes en la forma en que almacenan los valores.
  2. La precisión es la principal diferencia (Tenga en cuenta que esta no es la única diferencia) donde float es un tipo de datos de coma flotante de precisión simple (32 bits), double es un tipo de datos de coma flotante de doble precisión (64 bits) y decimal es de 128 bits tipo de datos de coma flotante
  3. La tabla de resumen:

 /========================================================================================== Type Bits Have up to Approximate Range /========================================================================================== float 32 7 digits -3.4 × 10 ^ (38) to +3.4 × 10 ^ (38) double 64 15-16 digits ±5.0 × 10 ^ (-324) to ±1.7 × 10 ^ (308) decimal 128 28-29 significant digits ±7.9 x 10 ^ (28) or (1 to 10 ^ (28) /========================================================================================== 

Puedes leer más aquí , Float , Double y Decimal .