¿Diferencia entre decimal, flotante y doble en .NET?

2230

¿Qué es la diferencia entre decimal, floaty doubleen .NET?

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

3
2413

floaty doubleson tipos de coma binaria flotante . 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.

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

12345.65789

Una vez más, el número y la ubicación del punto decimal están codificados dentro del valor; eso es lo que hace que decimalsiga 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 no enteros en forma decimal y esperan resultados exactos en representaciones decimales; no todos los números decimales son exactamente representables en coma flotante binaria - 0.1, por ejemplo - así que si usa un valor de coma flotante binaria en realidad obtendrá una aproximación a 0.1. También obtendrá aproximaciones cuando use un punto decimal flotante; por ejemplo, el resultado de dividir 1 entre 3 no se puede representar exactamente.

En cuanto a qué usar cuando:

  • Para valores que son "decimales naturalmente exactos", es bueno usarlos decimal. Esto suele ser 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 otorgada a los buceadores o patinadores sobre hielo, por ejemplo.

  • Para valores que son más objetos de la naturaleza que en realidad no puede medirse con exactitud todos modos, float/ doubleson más apropiados. Por ejemplo, los datos científicos suelen estar representados de esta forma. Aquí, los valores originales no serán "decimalmente precisos" 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.

13
  • 74
    float/ doublepor lo general no representan números como 101.101110, normalmente se representa como algo como 1101010 * 2^(01010010)- un exponenteMingwei Samuel 13/08/2014 a las 21:50
  • 88
    @Hazzard: Eso es lo que significa la parte "y la ubicación del punto binario" de la respuesta. Jon Skeet 13/0814 a las 21:57
  • 124
    Me sorprende que aún no se haya dicho, floates una palabra clave de alias de C # y no es un tipo .Net. es System.Single.. singley doubleson tipos de punto binario flotante. Brett Caswell 3 feb.15 a las 15:48
  • 60
    @BKSpurgeon: Bueno, solo de la misma manera que puedes decir que todo es de tipo binario, momento en el que se convierte en una definición bastante inútil. Decimal es un tipo decimal en el sentido de que es un número representado como un significando entero y una escala, de modo que el resultado es una escala significativa * 10 ^, mientras que flotante y doble son una escala significativa * 2 ^. Se toma un número escrito en decimal y se mueve el punto decimal lo suficiente hacia la derecha para obtener un número entero para calcular el significado y la escala. Para float / double, comenzaría con un número escrito en binario. Jon Skeet 26/11/15 a las 7:20
  • 30
    Otra diferencia: flotante de 32 bits; doble de 64 bits; y decimal de 128 bits. David 29 de agosto de 2016 a las 15:08
1142

La precisión es la principal diferencia.

Flotante : 7 dígitos (32 bits)

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

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

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 20 veces en algunas pruebas) que un doble / flotante.

Los decimales y los flotantes / dobles no se pueden comparar sin un elenco, mientras que los flotantes y los dobles sí. Los decimales también permiten la codificación o 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
35
  • 69
    @Thecrocodilehunter: lo siento, pero no. Decimal puede representar todos los números que se pueden representar en notación decimal, pero no 1/3, por ejemplo. 1.0m / 3.0m evaluará a 0.33333333 ... con un número grande pero finito de 3s al final. Multiplicarlo por 3 no arrojará un 1.0 exacto. Erik P. 29/11/11 a las 21:14
  • 55
    @Thecrocodilehunter: Creo que estás confundiendo exactitud y precisión. Son cosas diferentes en este contexto. La precisión es el número de dígitos disponibles para representar un número. Cuanto más precisión, menos necesitas redondear. Ningún tipo de datos tiene precisión infinita. Igby Largeman 6/01/12 a las 17:42
  • dieciséis
    @Thecrocodilehunter: Está asumiendo que el valor que se está midiendo es exactamente 0.1 , ¡eso rara vez es el caso en el mundo real! Cualquier formato de almacenamiento finito combinará un número infinito de valores posibles con un número finito de patrones de bits. Por ejemplo, floatse combinará 0.1y 0.1 + 1e-8, mientras que decimalse combinará 0.1y 0.1 + 1e-29. Claro, dentro de un rango dado , ciertos valores se pueden representar en cualquier formato sin pérdida de precisión (por ejemplo, floatpuede almacenar cualquier número entero hasta 1.6e7 sin pérdida de precisión), pero eso todavía no es una precisión infinita . Daniel Pryden 10 de enero de 2012 a las 1:49
  • 28
    @Thecrocodilehunter: No entendiste mi punto. no0.1 es un valor especial ! Lo único que hace que sea 0.1"mejor" que 0.10000001es porque a los seres humanos les gusta la base 10. E incluso con un floatvalor, si inicializas dos valores de 0.1la misma manera, ambos tendrán el mismo valor . Es solo que ese valor no será exactamente 0.1 , será el valor más cercano al 0.1que se puede representar exactamente como unfloat . Claro, con flotadores binarios (1.0 / 10) * 10 != 1.0, pero con flotadores decimales (1.0 / 3) * 3 != 1.0tampoco. Ninguno es perfectamente preciso. Daniel Pryden 10/01/12 a las 18:27
  • 19
    @Thecrocodilehunter: Todavía no lo entiendes. No sé cómo decir esto más claramente: en C, si lo haces double a = 0.1; double b = 0.1;, a == b será verdad . Es solo eso ay ambos no bserán exactamente iguales . En C #, si lo hace entonces también será cierto. Pero en ese caso, ni de ni serán exactamente iguales , ambos serán iguales . En ambos casos, se pierde algo de precisión debido a la representación. Dice obstinadamente que tiene una precisión "infinita", lo cual es falso . 0.1decimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m;a == bab1/30.3333...decimalDaniel Pryden 10/01/12 a las 19:29
97
+---------+----------------+---------+----------+---------------------------------------------------------+
| C#      | .Net Framework | Signed? | Bytes    | Possible Values                                         |
| Type    | (System) type  |         | Occupied |                                                         |
+---------+----------------+---------+----------+---------------------------------------------------------+
| sbyte   | System.Sbyte   | Yes     | 1        | -128 to 127                                             |
| short   | System.Int16   | Yes     | 2        | -32,768 to 32,767                                       |
| int     | System.Int32   | Yes     | 4        | -2,147,483,648 to 2,147,483,647                         |
| long    | System.Int64   | Yes     | 8        | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
| byte    | System.Byte    | No      | 1        | 0 to 255                                                |
| ushort  | System.Uint16  | No      | 2        | 0 to 65,535                                             |
| uint    | System.UInt32  | No      | 4        | 0 to 4,294,967,295                                      |
| ulong   | System.Uint64  | No      | 8        | 0 to 18,446,744,073,709,551,615                         |
| float   | System.Single  | Yes     | 4        | Approximately ±1.5e-45 to ±3.4e38                       |
|         |                |         |          |  with ~6-9 significant figures                          |
| double  | System.Double  | Yes     | 8        | Approximately ±5.0e-324 to ±1.7e308                     |
|         |                |         |          |  with ~15-17 significant figures                        |
| decimal | System.Decimal | Yes     | 16       | Approximately ±1.0e-28 to ±7.9e28                       |
|         |                |         |          |  with 28-29 significant figures                         |
| char    | System.Char    | N/A     | 2        | Any Unicode character (16 bit)                          |
| bool    | System.Boolean | N/A     | 1 / 2    | true or false                                           |
+---------+----------------+---------+----------+---------------------------------------------------------+

Consulte aquí para obtener más información .

3
  • 8
    Dejó fuera la mayor diferencia, que es la base utilizada para el tipo decimal (el decimal se almacena como base 10, todos los demás tipos numéricos enumerados son base 2). BrainSlugs83 14/03/15 a las 22:55
  • 1
    Los rangos de valores para Single y Double no se muestran correctamente en la imagen de arriba o en la publicación del foro fuente. Como no podemos superíndice fácilmente el texto aquí, use el carácter de intercalación: Single debe ser 10 ^ -45 y 10 ^ 38, y Double debe ser 10 ^ -324 y 10 ^ 308. Además, MSDN tiene el flotador con un rango de -3.4x10 ^ 38 a + 3.4x10 ^ 38. Busque en MSDN System.Single y System.Double en caso de cambios en el enlace. Individual: msdn.microsoft.com/en-us/library/b1e65aza.aspx Doble: msdn.microsoft.com/en-us/library/678hzkk9.aspxdeegee 22/06/15 a las 19:18
  • 3
    El decimal es de 128 bits ... significa que ocupa 16 bytes, no 12user1477332 23 oct 2018 a las 3:29
91

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 está midiendo. 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 base 10 (es decir, los flotantes y los dobles son manejados por el hardware FPU, como MMX / SSE , mientras que los decimales se calculan en software).
  • Decimal tiene un rango de valores inaceptablemente más pequeño 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.
1
  • 6
    Si está haciendo cálculos financieros, es absolutamente necesario que desarrolle sus propios tipos de datos o encuentre una buena biblioteca que se adapte a sus necesidades exactas. La precisión en un entorno financiero está definida por organismos de estándares (humanos) y tienen reglas localizadas muy específicas (tanto en el tiempo como en la geografía) sobre cómo hacer cálculos. Cosas como el redondeo correcto no se capturan en los tipos de datos numéricos simples en .Net. La capacidad de hacer cálculos es solo una pequeña parte del rompecabezas. James Moore 6/04/2016 a las 16:59
66

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

When would someone use one of these?

Utilice decimal para los valores contados

Utilice flotante / doble para los valores medidos

Algunos ejemplos:

  • dinero (¿contamos o medimos dinero?)

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

  • puntajes (¿contamos puntajes o medimos puntajes?)

Siempre contamos el dinero y nunca debemos medirlo. Por lo general, 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 estemos tratando con letreros 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).

1
  • 2
    Me gusta mucho esta respuesta, especialmente la pregunta "¿contamos o medimos el dinero?" Sin embargo, aparte del dinero, no puedo pensar en nada que sea "contado" que no sea simplemente un número entero. He visto algunas aplicaciones que usan decimal simplemente porque el doble tiene muy pocos dígitos significativos. En otras palabras, se puede usar decimal porque C # no tiene un tipo cuádruple en.wikipedia.org/wiki/Quadruple-precision_floating-point_formatJohn Henckel 4/04/19 a las 18:55
49

float 7 dígitos de precisión

double tiene unos 15 dígitos de precisión

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

Si necesita una mayor precisión, use 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 solo importa si tienes muchos de ellos.

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

6
  • 1
    @RogerLipscombe: lo consideraría doubleapropiado en aplicaciones de contabilidad en aquellos casos (y básicamente solo aquellos casos) donde no hay disponible un tipo de entero mayor de 32 bits, y doublese usa como si fuera un tipo de entero de 53 bits (por ejemplo, para mantener un número entero de centavos, o un número entero de centésimas de centavo). No es de mucha utilidad para tales cosas hoy en día, pero muchos lenguajes obtuvieron la capacidad de usar valores de punto flotante de doble precisión mucho antes de obtener matemáticas enteras de 64 bits (¡o en algunos casos incluso de 32 bits!). supercat 29 de mayo de 2014 a las 17:57
  • 1
    Su respuesta implica que la precisión es la única diferencia entre estos tipos de datos. Dado que la aritmética de punto flotante binario se implementa normalmente en FPU de hardware , el rendimiento es una diferencia significativa. Esto puede ser intrascendente para algunas aplicaciones, pero es fundamental para otras. saille 15 de enero de 2015 a las 3:16
  • 6
    @supercat double nunca es apropiado en aplicaciones contables. Porque Double solo puede aproximar valores decimales (incluso dentro del rango de su propia precisión). Esto se debe a que double almacena los valores en un formato centrado en base 2 (binario). BrainSlugs83 14/03/15 a las 22:50
  • 2
    @ BrainSlugs83: El uso de tipos de punto flotante para contener cantidades que no son números enteros sería incorrecto, pero históricamente era muy común que los lenguajes tuvieran tipos de punto flotante que pudieran representar con precisión valores de números enteros más grandes de lo que podrían representar sus tipos de números enteros . Quizás el ejemplo más extremo fue Turbo-87, cuyos únicos tipos enteros se limitaron a -32768 a +32767, pero cuyo RealIIRC podría representar valores de hasta 1.8E + 19 con precisión unitaria. Creo que sería mucho más sensato utilizar una aplicación de contabilidad Realpara representar un número entero de centavos que ...supercat 15 mar.15 a las 19:45
  • 1
    ... para que intente realizar matemáticas de precisión múltiple utilizando un grupo de valores de 16 bits. Para la mayoría de los otros lenguajes, la diferencia no fue tan extrema, pero durante mucho tiempo ha sido muy común que los lenguajes no tengan ningún tipo de entero que vaya más allá de 4E9, pero tengan un doubletipo que tenga una precisión de unidad de hasta 9E15. Si uno necesita almacenar números enteros que son más grandes que el tipo de entero más grande disponible, doublees probable que el uso sea más simple y más eficiente que tratar de manipular las matemáticas de precisión múltiple, especialmente dado que mientras que los procesadores tienen instrucciones para ejecutar 16x16-> 32 o. ..supercat 15 mar 15 a las 19:47
39

Nadie ha mencionado eso

In default settings, Floats (System.Single) and doubles (System.Double) will never use overflow checking while Decimal (System.Decimal) will always use overflow checking.

quiero decir

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

lanza OverflowException .

Pero estos no:

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

Y

double myNumber = double.MaxValue;
myNumber += 1;
4
  • 2
    float.MaxValue+1 == float.MaxValue, al igual que decimal.MaxValue+0.1D == decimal.MaxValue. ¿Quizás quisiste decir algo como float.MaxValue*2? supercat 14 de enero de 2015 a las 0:21
  • @supercar Pero no es cierto que decimal.MaxValue + 1 == decimal.MaxValueGorkemHalulu 14 de enero de 2015 a las 6:12
  • @supercar decimal.MaxValue + 0.1m == decimal.MaxValue okGorkemHalulu 14 de enero de 2015 a las 6:19
  • 1
    La System.Decimallanza una excepción justo antes de que se vuelve incapaz de distinguir unidades enteras, pero si se supone una aplicación que se trata de dólares y centavos, por ejemplo, que podría ser demasiado tarde. supercat 14 de enero de 2015 a las 16:15
28

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. Puede utilizar el tipo doble o el tipo flotante. Configura estos tipos de variables exactamente de la misma manera: en lugar de usar la palabra int, escribe doubleo float. Como esto:

float myFloat;
double myDouble;

( floates la abreviatura de "punto flotante" y solo significa un número con un punto al final).

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 doubles, 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

floates un número de 32 bits y doublees un número de 64 bits.

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

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

Detén tu programa y regresa a la ventana de codificación. Cambie esta línea:

myDouble = 0.007;
myDouble = 12345678.1234567;

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

1
  • 3
    El "señalar algo" que mencionaste generalmente se conoce como "la parte fraccionaria" de un número. "Punto flotante" no significa "un número con un punto al final"; pero en cambio "Floating Point" distingue el tipo de número, a diferencia de un número de "Fixed Point" (que también puede almacenar un valor fraccionario); la diferencia es si la precisión es fija o flotante. - Los números de coma flotante le brindan un rango dinámico de valores mucho mayor (Mín. Y Máx.), A costa de la precisión, mientras que los números de coma fija le brindan una cantidad constante de precisión a costa del rango. BrainSlugs83 16 de septiembre de 2017 a las 1:09
27
  1. Double y float se pueden dividir por un número entero cero sin excepción tanto en la compilación como en el tiempo de ejecución.
  2. El decimal no se puede dividir por un número entero cero. La compilación siempre fallará si haces eso.
3
  • 6
    ¡Seguro que pueden! También tienen un par de valores "mágicos" como Infinity, Negative Infinity y NaN (no es un número) que lo hacen muy útil para detectar líneas verticales mientras calcula pendientes ... Además, si necesita decidir entre llamar a float . TryParse, double.TryParse y decimal.TryParse (para detectar si una cadena es un número, por ejemplo), recomiendo usar double o float, ya que analizarán "Infinity", "-Infinity" y "NaN" correctamente , mientras que decimal no lo hará. BrainSlugs83 23/06/11 a las 19:29
  • 1
    La compilación solo falla si intenta dividir un literal decimalpor cero (CS0020), y lo mismo ocurre con los literales integrales. Sin embargo, si un valor decimal en tiempo de ejecución se divide por cero, obtendrá una excepción, no un error de compilación. Drew Noakes 18 de noviembre de 2016 a las 0:24
  • @ BrainSlugs83 Sin embargo, es posible que no desee analizar "Infinity" o "NaN" según el contexto. Parece un buen exploit para la entrada del usuario si el desarrollador no es lo suficientemente riguroso. Winter 17 de mayo de 2017 a las 13 h.
17
  • flotación: ± 1,5 x 10 ^ -45 a ± 3,4 x 10 ^ 38 (~ 7 cifras significativas
  • doble: ± 5.0 x 10 ^ -324 a ± 1.7 x 10 ^ 308 (15-16 cifras significativas)
  • decimal: ± 1.0 x 10 ^ -28 a ± 7.9 x 10 ^ 28 (28-29 cifras significativas)
1
  • 10
    La diferencia es más que precisión. - en decimalrealidad se almacena en formato decimal (a diferencia de la base 2; por lo que no perderá ni redondeará dígitos debido a la conversión entre los dos sistemas numéricos); además, decimalno tiene ningún concepto de valores especiales como NaN, -0, ∞ o -∞. BrainSlugs83 16 de septiembre de 2017 a las 1:19
13

Los tipos de variables Decimal, Double 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 punto flotante de precisión simple (32 bits), double 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.

Flotante - 32 bits (7 dígitos)

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

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

Más sobre ... la diferencia entre decimal, flotante y doble

1
  • ¿Alguien sabe por qué estos diferentes dígitos varían para cada tipo? Andrea Leganza 4 de febrero a las 11:06
11

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

En nuestro código C #, leemos valores numéricos de una hoja de cálculo de Excel, los convertimos en a decimaly luego los enviamos de decimalvuelta a un servicio para guardarlos 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ó a la perfección. Pero para algunos valores de Excel muy pequeños, el uso decimal.TryParseperdió el valor por completo. Un ejemplo es

  • cellValue = 0.00006317592

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

La solución, curiosamente, fue convertir los valores de Excel en un doubleprimero 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;
    …
}

Aunque doubletiene menos precisión que a decimal, esto realmente aseguró que aún se reconocerían números pequeños. Por alguna razón, double.TryParsefue capaz de recuperar números tan pequeños, mientras que los decimal.TryParsepondría a cero.

Impar. Muy raro.

6
  • 4
    Por curiosidad, ¿cuál fue el valor bruto de cellValue.ToString ()? Decimal. TryParse ("0.00006317592", out val) parece funcionar ...micahtan 27 de agosto de 2012 a las 23:57
  • 12
    -1 No me malinterpretes, si es cierto, es muy interesante, pero esta es una pregunta separada, ciertamente no es una respuesta a esta pregunta. weston 22 de mayo de 2013 a las 14:19
  • 3
    Tal vez porque la celda de Excel estaba devolviendo un valor doble y ToString () era "6.31759E-05", por lo tanto, al decimal.Parse () no le gustó la notación. Apuesto a que si verificaras el valor de retorno de Decimal.TryParse () habría sido falso. SergioL 15/10/2014 a las 20:44
  • 2
    Las respuestas de @weston a menudo complementan otras respuestas al completar los matices que se han perdido. Esta respuesta destaca una diferencia en términos de análisis. ¡Es en gran medida una respuesta a la pregunta! Robino 20 de mayo de 2015 a las 15:52
  • 2
    Er ... decimal.Parse("0.00006317592")funciona - tienes algo más en marcha. - ¿Posiblemente notación científica? BrainSlugs83 16 de septiembre de 2017 a las 1:15
8

Para aplicaciones como juegos y sistemas embebidos donde la memoria y el rendimiento son críticos, float suele ser 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 números enteros solían ser el arma preferida, pero el rendimiento del punto flotante ha superado al número entero en los procesadores modernos. ¡Decimal está fuera de lugar!

2
  • Prácticamente todos los sistemas modernos, incluso los teléfonos móviles, tienen soporte de hardware para el doble; y si tu juego tiene una física incluso simple, notarás una gran diferencia entre doble y flotante. (Por ejemplo, al calcular la velocidad / fricción en un clon simple de Asteroides, los dobles permiten que la aceleración fluya de manera mucho más fluida que la flotación. Parece que no debería importar, pero lo hace totalmente)BrainSlugs83 16 de septiembre de 2017 a las 1:22
  • Los dobles también tienen el doble del tamaño de los flotadores, lo que significa que debe procesar el doble de datos, lo que perjudica el rendimiento de su caché. Como siempre, mida y proceda en consecuencia. yoyo 22 de septiembre de 2017 a las 17:53
5

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 VERDADERO!

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

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

Precaución: Creo que el mismo problema ciertamente puede existir para otro número 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 al decimal BINARY 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 el siguiente 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) 
4

En palabras simples:

  1. Los tipos de variables Decimal, Double 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 punto flotante de precisión simple (32 bits), double 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 tipo de datos de coma flotante.
  3. La tabla 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 .
2
  • 1
    ¿Qué agrega esta respuesta que no esté ya cubierto en las respuestas existentes? Por cierto, su "o" en la línea "decimal" es incorrecto: la barra en la página web desde la que está copiando indica división en lugar de una alternativa. Mark Dickinson 10 feb 2018 a las 12:15
  • 2
    Y discutiría firmemente que la precisión es la principal diferencia. La principal diferencia es la base: coma flotante decimal versus coma flotante binaria. Esa diferencia es lo que lo hace Decimaladecuado para aplicaciones financieras, y es el criterio principal a utilizar al decidir entre Decimaly Double. Es raro que la Doubleprecisión no sea suficiente para aplicaciones científicas, por ejemplo (y a Decimalmenudo no es adecuada para aplicaciones científicas debido a su rango limitado). Mark Dickinson 10 feb 2018 a las 12:28
3
  • Decimal 128 bit (28-29 dígitos significativos) En el caso de aplicaciones financieras, es mejor usar tipos decimales porque le brinda un alto nivel de precisión y es fácil evitar errores de redondeo Use decimal para matemáticas no enteras donde se necesita precisión (p. Ej. dinero y moneda)

  • Doble 64 bits (15-16 dígitos) Los tipos dobles son probablemente el tipo de datos más utilizado para valores reales, excepto para el manejo de dinero. Use doble para matemáticas no enteras donde la respuesta más precisa no es necesaria.

  • Float 32 bit (7 dígitos) Se utiliza mayoritariamente en librerías gráficas debido a demandas muy elevadas de potencias de procesamiento, también se utilizan situaciones que pueden soportar errores de redondeo.

Decimalsson mucho más lentos que a double/float.

Decimalsy Floats/Doublesno se puede comparar sin un yeso mientras que Floatsy se Doublespuede.

Decimals también permite la codificación o ceros finales.

2

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

floates un 32-bitnúmero, doublees un 64-bitnúmero y decimales un 128-bitnúmero.

-3

Para definir decimal, flotante y doble en .Net (c #)

debe mencionar valores como:

Decimal dec = 12M/6;
Double dbl = 11D/6;
float fl = 15F/6;

y comprobar los resultados.

Y los bytes ocupados por cada uno son

Float - 4
Double - 8
Decimal - 12