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

Respuestas:

2267

floaty doubleson tipos de punto binario 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

Nuevamente, el número y la ubicación del punto decimal están codificados dentro del valor; eso es lo que hace que sea decimalun 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 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, obtendrá una aproximación de 0.1. También obtendrá aproximaciones cuando utilice un punto decimal flotante; por ejemplo, el resultado de dividir 1 por 3 no puede representarse exactamente.

En cuanto a qué usar cuando:

  • Para valores que son "decimales exactos de forma natural" es bueno usarlo decimal. Esto suele ser adecuado para cualquier concepto inventado por los 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 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 generalmente se representarían de esta forma. Aquí, los valores originales no serán "decimalmente precisos" para comenzar, por lo que no es importante que los resultados esperados mantengan la "precisión decimal". Los tipos de punto binario flotante son mucho más rápidos para trabajar que los decimales.

Jon Skeet
fuente
58
float/ doublegeneralmente no representan números como 101.101110, normalmente se representa como algo así como 1101010 * 2^(01010010)un exponente
Mingwei Samuel
79
@Hazzard: Eso es lo que significa la parte "y la ubicación del punto binario" de la respuesta.
Jon Skeet
112
Me sorprende que no se haya dicho ya, floates una palabra clave de alias C # y no es un tipo .Net. susSystem.Single ... singley doubleson tipos de punto binario flotante.
Brett Caswell
54
@BKSpurgeon: Bueno, solo de la misma manera que puedes decir que todo es un tipo binario, en cuyo punto 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 significado entero y una escala, de modo que el resultado es una escala significand * 10 ^, mientras que flotante y doble son una escala significand * 2 ^. Tomas un número escrito en decimal y mueves el punto decimal lo suficiente a la derecha como para tener un número entero para calcular el significado y la escala. Para float / double comenzarías con un número escrito en binario.
Jon Skeet
21
Otra diferencia: flotador de 32 bits; doble de 64 bits; y decimal de 128 bits.
David
1073

La precisión es la principal diferencia.

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

Los decimales y los flotadores / dobles no se pueden comparar sin un yeso, mientras que los flotadores 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
cgreeno
fuente
65
@ 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 se evaluará a 0.33333333 ... con un número grande pero finito de 3s al final. Multiplicarlo por 3 no devolverá un 1.0 exacto.
Erik P.
50
@ Thecrocodilehunter: Creo que estás confundiendo precisión 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. A mayor precisión, menos necesita redondear. Ningún tipo de datos tiene una precisión infinita.
Igby Largeman
13
@Thecrocodilehunter: Estás 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 fusionará 0.1y 0.1 + 1e-8, mientras decimalse fusionará 0.1y 0.1 + 1e-29. Claro, dentro de un rango dado , ciertos valores pueden representarse en cualquier formato con cero pérdida de precisión (por ejemplo, floatpuede almacenar cualquier número entero de hasta 1.6e7 con cero pérdida de precisión), pero eso no es una precisión infinita .
Daniel Pryden
27
@ Thecrocodilehunter: Te perdiste mi punto. no0.1 es un valor especial ! Lo único que lo hace 0.1"mejor" 0.10000001es que a los seres humanos les gusta la base 10. E incluso con un floatvalor, si inicializas dos valores de 0.1la misma manera, ambos será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 afloat . Claro, con flotantes binarios (1.0 / 10) * 10 != 1.0, pero con flotantes decimales, (1.0 / 3) * 3 != 1.0tampoco. Ninguno de los dos es perfectamente preciso.
Daniel Pryden
16
@ Thecrocodilehunter: Todavía no entiendes. No sé cómo decir esto más claramente: en C, si lo haces, double a = 0.1; double b = 0.1;entonces a == b será cierto . 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 hará exactamente igual - igual que lo harán tanto . En ambos casos, se pierde algo de precisión debido a la representación. Usted tercamente dice que tiene una precisión "infinita", que es falsa . 0.1decimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m;a == bab1/30.3333...decimal
Daniel Pryden
84

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 está midiendo. La pérdida de precisión no es aceptable en las 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 coma flotante se realizan en binario, mientras que el decimal se realiza en la base 10 (es decir, los flotadores y los dobles son manejados por el hardware de la FPU, como MMX / SSE , mientras que los decimales se calculan en software).
  • Decimal tiene un rango de valores inaceptablemente menor que el doble, a pesar del hecho de que admite más dígitos de precisión. Por lo tanto, Decimal no se puede usar para representar muchos valores científicos.
Mark Jones
fuente
55
Si está haciendo cálculos financieros, absolutamente tiene que rodar sus propios tipos de datos o encontrar una buena biblioteca que coincida con sus necesidades exactas. La precisión en un entorno financiero está definida por los organismos de normalización (humanos) y tienen reglas localizadas muy específicas (tanto en tiempo como en geografía) sobre cómo hacer los 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 parte muy pequeña del rompecabezas.
James Moore
76
+---------+----------------+---------+----------+---------------------------------------------+
| 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                               |
+---------+----------------+---------+----------+---------------------------------------------+

Ver aquí para más información .

Uwe Keim
fuente
55
Omitió 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
1
Los rangos de valores para Single y Double no se representan correctamente en la imagen de arriba o en la publicación del foro de origen. Como no podemos superponer fácilmente el texto aquí, use el carácter de intercalación: Single debería ser 10 ^ -45 y 10 ^ 38, y Double debería ser 10 ^ -324 y 10 ^ 308. Además, MSDN tiene el flotante con un rango de -3.4x10 ^ 38 a + 3.4x10 ^ 38. Busque MSDN para System.Single y System.Double en caso de cambios de enlace. Individual: msdn.microsoft.com/en-us/library/b1e65aza.aspx Doble: msdn.microsoft.com/en-us/library/678hzkk9.aspx
deegee
2
El decimal es de 128 bits ... significa que ocupa 16 bytes, no 12
user1477332
51

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

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

Usar decimal para 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 el dinero y nunca debemos medirlo. Usualmente medimos la distancia. A menudo contamos los puntajes.

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

tomosius
fuente
1
Realmente me gusta esta respuesta, especialmente la pregunta "¿contamos o medimos el dinero?" Sin embargo, aparte del dinero, no puedo pensar en nada que se "cuente" que no sea simplemente entero. He visto algunas aplicaciones que usan decimal simplemente porque double tiene muy pocos dígitos significativos. En otras palabras, el decimal podría usarse porque C # no tiene un tipo cuádruple en.wikipedia.org/wiki/Quadruple-precision_floating-point_format
John Henckel
48

float 7 dígitos de precisión

double tiene unos 15 dígitos de precisión

decimal tiene unos 28 dígitos de precisión

Si necesita una mayor precisión, use doble en lugar de flotante. 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

CharithJ
fuente
1
@RogerLipscombe: consideraría doubleapropiado en aplicaciones de contabilidad en aquellos casos (y básicamente solo en aquellos casos) en los que no estaba disponible ningún tipo de entero mayor de 32 bits, y doublese estaba utilizando 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). Hoy en día no se usa mucho para tales cosas, pero muchos lenguajes obtuvieron la capacidad de usar valores de punto flotante de doble precisión mucho antes de que obtuvieran matemáticas enteras de 64 bits (¡o en algunos casos incluso de 32 bits!).
supercat
1
Su respuesta implica que la precisión es la única diferencia entre estos tipos de datos. Dado que la aritmética de coma flotante binaria generalmente se implementa en la FPU de hardware , el rendimiento es una diferencia significativa. Esto puede ser intrascendente para algunas aplicaciones, pero es crítico para otras.
saille
66
@supercat double nunca es apropiado en aplicaciones de contabilidad. 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 céntrico base-2 (binario).
BrainSlugs83
2
@ BrainSlugs83: El uso de tipos de punto flotante para contener cantidades que no sean números enteros sería incorrecto, pero históricamente era muy común que los idiomas 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 enteros. . Quizás el ejemplo más extremo fue Turbo-87, cuyos únicos tipos enteros estaban limitados de -32768 a +32767, pero cuyo RealIIRC podría representar valores de hasta 1.8E + 19 con precisión de unidad. Creo que sería mucho más sensato usar una aplicación de contabilidad Realpara representar un número entero de centavos que ...
supercat
1
... para que intente realizar operaciones matemáticas de precisión múltiple utilizando un montón de valores de 16 bits. Para la mayoría de los otros idiomas, la diferencia no fue tan extrema, pero durante mucho tiempo ha sido muy común que los idiomas no tengan ningún tipo entero que vaya más allá del 4E9, sino que 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 entero más grande disponible, usar doublees más simple y más eficiente que tratar de evitar las matemáticas de precisión múltiple, especialmente dado que los procesadores tienen instrucciones para realizar 16x16-> 32 o. ..
supercat
36

Nadie ha mencionado eso

En la configuración predeterminada, los flotantes (System.Single) y los dobles (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;

Y

double myNumber = double.MaxValue;
myNumber += 1;
GorkemHalulu
fuente
1
float.MaxValue+1 == float.MaxValue, igual que decimal.MaxValue+0.1D == decimal.MaxValue. ¿Quizás quisiste decir algo así float.MaxValue*2?
supercat
@supercar Pero no es cierto ese decimal.MaxValue + 1 == decimal.MaxValue
GorkemHalulu
@supercar decimal.MaxValue + 0.1m == decimal.MaxValue ok
GorkemHalulu
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
28
  1. Double y float se pueden dividir por entero cero sin una excepción tanto en la compilación como en el tiempo de ejecución.
  2. El decimal no se puede dividir por el entero cero. La compilación siempre fallará si haces eso.
xport
fuente
66
¡Seguro que pueden! También tienen un par de valores "mágicos" como Infinito, Infinito negativo y NaN (no un número) que lo hacen muy útil para detectar líneas verticales mientras se calculan las pendientes ... Además, si necesita decidir entre llamar flotante . 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 el decimal no lo hará.
BrainSlugs83
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
@ BrainSlugs83 Sin embargo, es posible que no desee analizar "Infinito" o "NaN" según el contexto. Parece un buen exploit para la entrada del usuario si el desarrollador no es lo suficientemente riguroso.
Invierno
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 usar 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. Me gusta esto:

float myFloat;
double myDouble;

( floates la abreviatura de "punto flotante", y solo significa un número con un punto algo 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 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 su botón doble. El cuadro de mensaje muestra correctamente el número. Sin embargo, agregue otro número al final y C # nuevamente se redondeará hacia arriba o hacia abajo. La moraleja es que si quieres precisión, ¡ten cuidado de redondear!

daniel
fuente
2
El "señalar algo" que mencionó generalmente se conoce como "la parte fraccionaria" de un número. "Punto flotante" no significa "un número con un punto algo al final"; pero en su lugar, "Punto flotante" distingue el tipo de número, en oposición a un número de "Punto fijo" (que también puede almacenar un valor fraccionario); la diferencia es si la precisión es fija o flotante. - Los números de punto 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 punto fijo le brindan una cantidad constante de precisión al costo del rango.
BrainSlugs83
16
  • flotante: ± 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)
Mukesh Kumar
fuente
99
La diferencia es más que solo precisión. - en decimalrealidad se almacena en formato decimal (a diferencia de la base 2; por lo que no perderá ni redondeará los 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
13

Este ha sido un hilo interesante para mí, ya que hoy, hemos tenido un pequeño error desagradable, con respecto a decimaltener menos precisión que a 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ó maravillosamente. Pero para algunos valores de Excel muy pequeños, el uso decimal.TryParseperdió el valor por completo. Uno de esos ejemplos es

  • cellValue = 0.00006317592

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

La solución, extrañamente, 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;
    
}

A pesar de que 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 decimal.TryParseque los puso a cero.

Impar. Muy raro.

Mike Gledhill
fuente
3
Por curiosidad, ¿cuál fue el valor bruto de cellValue.ToString ()? Decimal.TryParse ( ",00006317592", fuera val) parece que funciona ...
micahtan
11
-1 No me malinterpreten, si es cierto, es muy interesante, pero esta es una pregunta separada, ciertamente no es una respuesta a esta pregunta.
Weston
2
Tal vez porque la celda de Excel estaba devolviendo un doble y el valor de ToString () era "6.31759E-05", por lo tanto, al decimal.Parse () no le gustó la notación. Apuesto a que si marcó el valor de retorno de Decimal. TryParse () habría sido falso.
SergioL
2
@weston Las respuestas 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
1
Er ... decimal.Parse("0.00006317592")funciona, tienes algo más que hacer. - Posiblemente notación científica?
BrainSlugs83
9

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

yoyó
fuente
Casi todos los sistemas modernos, incluso los teléfonos celulares, 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 simple clon de asteroides, los dobles permiten que la aceleración fluya mucho más fluidamente que flotar. Parece que no debería importar, pero lo hace totalmente)
BrainSlugs83
Los dobles también son el doble del tamaño de los flotadores, lo que significa que debe analizar el doble de datos, lo que perjudica el rendimiento de su caché. Como siempre, mida y proceda en consecuencia.
yoyo
7

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 donde flotante es un tipo de datos de coma flotante de precisión simple (32 bits), el doble es un tipo de datos de coma flotante de doble precisión (64 bits) y el decimal es un tipo de datos de coma flotante de 128 bits.

Flotador: 32 bits (7 dígitos)

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

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

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

Warnerl
fuente
5

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 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 BINARIO 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) 
Schlebe
fuente
4

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 principal diferencia (tenga en cuenta que esta no es la única diferencia) donde flotante es un tipo de datos de coma flotante de precisión simple (32 bits), doble es un tipo de datos de coma flotante de precisión doble (64 bits) y decimal es un 128 bits tipo de datos de punto 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)
/==========================================================================================
Puedes leer más aquí , Flotante , Doble y Decimal .

GntS
fuente
¿Qué agrega esta respuesta que no está cubierta en las respuestas existentes? Por cierto, su "o" en la línea "decimal" es incorrecta: la barra en la página web que está copiando indica división en lugar de una alternativa.
Mark Dickinson
1
Y discutiría fuertemente que la precisión es la principal diferencia. La principal diferencia es la base: punto flotante decimal versus punto flotante binario. 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 alcance limitado).
Mark Dickinson
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.

usuario3776645
fuente
0
  • Decimal de 128 bits (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 cálculos no enteros donde se necesita precisión (p. Ej. dinero y moneda)

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

  • Flotante de 32 bits (7 dígitos) Se utiliza principalmente en bibliotecas gráficas porque las demandas de potencia de procesamiento son muy altas, también se utilizan situaciones que pueden soportar errores de redondeo.

Decimals son mucho más lentos que un double/float .

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

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

Reza Jenabi
fuente
-1

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 verifica los resultados.

Y los bytes ocupados por cada uno son

Float - 4
Double - 8
Decimal - 12
Purnima Bhatia
fuente