Pregunta

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

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

¿Fue útil?

Solución

float y double son flotante < em> binary tipos de puntos . 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 punto decimal flotante escribe . En otras palabras, representan un número como este:

12345.65789

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

Lo importante a tener en cuenta es que los seres humanos están acostumbrados a representar no enteros en forma decimal, y esperan resultados exactos en representaciones decimales; no todos los números decimales se pueden representar exactamente en punto flotante binario (0.1, por ejemplo), por lo tanto, si usa un valor de punto flotante binario, en realidad obtendrá una aproximación de 0.1. También obtendrá aproximaciones cuando use un punto decimal flotante, por ejemplo, el resultado de dividir 1 por 3 no se puede representar con exactitud.

En cuanto a qué usar cuando:

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

  • Para los valores que son más artefactos de la naturaleza que realmente no se pueden medir exactamente de todos modos, float / double son más apropiado. Por ejemplo, los datos científicos por lo general se representan en esta forma. Aquí, los valores originales no serán " decimalmente exactos " 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 para trabajar que los decimales.

Otros consejos

La precisión es la principal diferencia.

Float - 7 dígitos (32 bits)

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

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

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

Los decimales y los Flotantes / Dobles no se pueden comparar sin un lanzamiento, mientras que los Flotantes y Dobles se pueden comparar. Los decimales también permiten la codificación 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. Sin embargo, los decimales no son adecuados para aplicaciones científicas, 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 finanzas.
  • El decimal es mucho (mucho) más lento que el flotante y el doble para la mayoría de las operaciones, principalmente porque las operaciones de punto flotante se realizan en binario, mientras que el decimal se realiza en la base 10 (es decir, el hardware de la FPU maneja los flotantes y los dobles, como MMX / SSE, mientras que los decimales se calculan en el 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 utilizar para representar muchos valores científicos.
+---------+----------------+---------+----------+---------------------------------------------+
| C#      | .Net Framework | Signed? | Bytes    | Possible Values                             |
| Type    | (System) type  |         | Occupied |                                             |
+---------+----------------+---------+----------+---------------------------------------------+
| sbyte   | System.Sbyte   | Yes     | 1        | -128 to 127                                 |
| short   | System.Int16   | Yes     | 2        | -32768 to 32767                             |
| int     | System.Int32   | Yes     | 4        | -2147483648 to 2147483647                   |
| long    | System.Int64   | Yes     | 8        | -9223372036854775808 to 9223372036854775807 |
| byte    | System.Byte    | No      | 1        | 0 to 255                                    |
| ushort  | System.Uint16  | No      | 2        | 0 to 65535                                  |
| uint    | System.UInt32  | No      | 4        | 0 to 4294967295                             |
| ulong   | System.Uint64  | No      | 8        | 0 to 18446744073709551615                   |
| float   | System.Single  | Yes     | 4        | Approximately ±1.5 x 10-45 to ±3.4 x 1038   |
|         |                |         |          |  with 7 significant figures                 |
| double  | System.Double  | Yes     | 8        | Approximately ±5.0 x 10-324 to ±1.7 x 10308 |
|         |                |         |          |  with 15 or 16 significant figures          |
| decimal | System.Decimal | Yes     | 12       | Approximately ±1.0 x 10-28 to ±7.9 x 1028   |
|         |                |         |          |  with 28 or 29 significant figures          |
| char    | System.Char    | N/A     | 2        | Any Unicode character (16 bit)              |
| bool    | System.Boolean | N/A     | 1 / 2    | true or false                               |
+---------+----------------+---------+----------+---------------------------------------------+

Para más información, vea:
http: //social.msdn .microsoft.com / Forums / en-US / csharpgeneral / thread / 921a8ffc-9829-4145-bdc9-a96c1ec174a5

float 7 dígitos de precisión

double tiene aproximadamente 15 dígitos de precisión

decimal tiene aproximadamente 28 dígitos de precisión

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

He encontrado que esto es interesante. Lo que todo científico informático debe saber sobre la aritmética de punto flotante

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

  

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

Usa el decimal para valores contados

Utilice float / double para valores medidos

Algunos ejemplos:

  • dinero (¿contamos el dinero o medimos el dinero?)

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

  • puntuaciones (¿contamos las puntuaciones o las medimos?)

Siempre contamos el dinero y nunca debemos medirlo. Normalmente medimos la distancia. A menudo contamos puntuaciones.

* En algunos casos, lo que yo llamaría distancia nominal , es posible que queramos "contar" la distancia. Por ejemplo, tal vez estamos tratando con signos de países que muestran distancias a ciudades, y sabemos que esas distancias nunca tienen más de un dígito decimal (xxx.x km).

Nadie ha mencionado eso

  

En la configuración predeterminada, Floats (System.Single) y doubles (System.Double) nunca se usarán   comprobación de desbordamiento mientras que Decimal (System.Decimal) siempre usará   comprobación de desbordamiento.

Quiero decir

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

lanza OverflowException .

Pero estos no:

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

& amp;

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

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

float myFloat;
double myDouble;

( float es la abreviatura de " coma 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, aquí está 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.

Haz doble clic en tu 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 programa y regrese a la ventana de codificación. Cambia esta línea:

myDouble = 0.007;
myDouble = 12345678.1234567;

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

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

Este ha sido un tema interesante para mí, ya que hoy hemos tenido un pequeño error desagradable, en relación con decimal que tiene menos precisión que un flotador .

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

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 de nuestros valores de Excel, esto funcionó a la perfección. Pero para algunos valores de Excel muy pequeños, el uso de decimal.TryParse perdió el valor completamente. Un ejemplo es

  • cellValue = 0.00006317592

  • Decimal.TryParse (cellValue.ToString (), out value); // devolvería 0

La solución, extrañamente, fue convertir los valores de Excel en un doble 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 double tiene menos precisión que un decimal , esto en realidad aseguró que los pequeños números aún serían reconocidos. Por alguna razón, double.TryParse fue capaz de recuperar números tan pequeños, mientras que decimal.TryParse se establecería ellos a cero.

Impar. Muy extraño.

  • flotador: & # 177; 1.5 x 10 ^ -45 a & # 177; 3.4 x 10 ^ 38 (~ 7 cifras significativas
  • doble: & # 177; 5.0 x 10 ^ -324 a & # 177; 1.7 x 10 ^ 308 (15-16 cifras significativas)
  • decimal: & # 177; 1.0 x 10 ^ -28 a & # 177; 7.9 x 10 ^ 28 (28-29 cifras significativas)

Para aplicaciones tales como juegos y sistemas integrados donde la memoria y el rendimiento son críticos, float es generalmente el tipo numérico de elección, ya que es más rápido y tiene la mitad del tamaño de un doble. Los enteros solían ser el arma de elección, pero el rendimiento de punto flotante ha superado a los enteros en los procesadores modernos. ¡El decimal está listo!

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

Flotante - 32 bits (7 dígitos)

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

Decimal: 128 bits (28-29 dígitos significativos)

Más acerca de ... la diferencia entre Decimal, Flotante y Doble

El problema con todos estos tipos es que subsiste una 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 sustituyo Doble por decimal, bLower contiene FALSO, que es la buena respuesta.

En doble, el problema es que fMean-fDelta = 1.09999999999 que es inferior a 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 después del 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) 

En palabras simples:

  1. Los tipos de variable Decimal, Double y Float son diferentes en la forma en que almacenan los valores.
  2. La precisión es la diferencia principal (observe que esta no es la única diferencia) donde flotador es una precisión única (32 bits) flotante el tipo de datos de punto, doble es un tipo de datos de punto flotante de doble precisión (64 bits) y decimal es un tipo de datos de punto flotante de 128 bits.
  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)
/==========================================================================================
Puede leer más aquí , Float , Double , y Decimal .

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 .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top