Siempre digo en c# una variable de tipo double que no es adecuado para el dinero. Todas las cosas raras que podría suceder. Pero me parece que no puede crear un ejemplo para demostrar algunas de estas cuestiones. ¿Alguien puede proporcionar un ejemplo?

(edición; este post fue originalmente marcada en C#; algunas respuestas se refieren a los detalles específicos de decimal, lo que significa Sistema.Decimal).

(edit 2: me fue específicos pidiendo algo de código de c#, así que no creo que esto es independiente del idioma sólo)

InformationsquelleAutor doekman | 2008-11-25

8 Comentarios

  1. 114

    Muy, muy inadecuado. El uso de decimales.

    double x = 3.65, y = 0.05, z = 3.7;
    Console.WriteLine((x + y) == z); //false

    (ejemplo de Jon página aquí – se recomienda la lectura ;-p)

    • Maldita sea, si yo hubiera sabido que tenía un ejemplo en mi propia página, no me han llegado con una diferente 😉
  2. 34

    Obtendrá impar errores de manera efectiva causada por el redondeo. Además, las comparaciones con los valores exactos son extremadamente complicado, suele ser necesario aplicar algún tipo de epsilon para comprobar el valor real de estar «cerca» de un particular.

    Aquí un ejemplo concreto:

    using System;
    
    class Test
    {
        static void Main()
        {
            double x = 0.1;
            double y = x + x + x;
            Console.WriteLine(y == 0.3); //Prints False
        }
    }
    • Si usted está consumiendo un servicio que devuelve el doble del valor de la moneda que usted no puede controlar hay trampas a pensar en convertir a formato decimal ? La pérdida de precisión, etc…
    • Absolutamente – fundamentalmente, que la rotura de una manera de hacer las cosas, y usted necesita saber cómo son mejores para interpretar los datos.
    • Gracias, parece que tenemos algo de trabajo que hacer.
  3. 7

    Sí, es inadecuado.

    Si recuerdo correctamente doble tiene alrededor de 17 números significativos, por lo que normalmente los errores de redondeo tendrá lugar lejos detrás de la coma decimal. La mayoría de software financiero utiliza 4 decimales detrás de la coma decimal, que deja 13 decimales para trabajar con el máximo número que puede trabajar con una sola operación, es todavía mucho mayor que el de estados UNIDOS de la deuda nacional. Pero los errores de redondeo se suman con el tiempo. Si el software se ejecuta durante un tiempo prolongado, el tiempo va a empezar a perder centavos. Ciertas operaciones va a empeorar esta situación. Por ejemplo, la adición de grandes cantidades de pequeñas cantidades a causar una pérdida significativa de precisión.

    Necesita de punto fijo de tipos de datos para operaciones de dinero, la mayoría de la gente no le importa si pierde un centavo aquí y allí, pero los contadores no son como la mayoría de la gente..

    editar

    De acuerdo a este sitio http://msdn.microsoft.com/en-us/library/678hzkk9.aspx Dobles en realidad tienen de 15 a 16 dígitos significativos en lugar de 17.

    @Jon Skeet decimal es más adecuado que el doble, debido a su mayor precisión, 28 o 29 significativo decimales. Eso significa menos posibilidades de acumulación de errores de redondeo convirtiendo en importantes. Punto fijo de tipos de datos (es decir, números enteros que representan centavos o 100th de un centavo como las que he visto utilizado) como el Cirio menciona son en realidad la más adecuada.

    • Tenga en cuenta que el Sistema.Decimal, se sugiere que el tipo a utilizar en .NET, es todavía un tipo de punto flotante – pero es un punto decimal flotante en lugar de un flotante binario de punto. Eso es más importante que tener una precisión fija en la mayoría de los casos, sospecho.
    • Ese es precisamente el problema. La moneda es hoy en día normalmente decimal. De vuelta antes de que los mercados bursátiles de estados unidos decimalized, sin embargo, binario fracciones estaban en uso (empecé a ver 256ths e incluso 1024ths en un punto) y dobla así hubiera sido más apropiado que el de decimales para los precios de las acciones! Pre-decimalization libras esterlinas habría sido un verdadero dolor de cabeza a 960 moneditas a la libra; que no es ni decimal ni binario, pero sin duda ofrece una generosa variedad de factores primos para facilitar las fracciones.
    • Incluso más importante que beind un punto flotante decimal, decimal la expresión x + 1 != x siempre es cierto. También, se conserva la precisión, por lo que usted puede decir la diferencia entre 1 y 1.0.
    • Estas propiedades sólo son significativos si una de las escalas de uno de los valores de modo que un valor de 1 representa la menor unidad de la moneda. Un Decimal valor puede perder precisión a la derecha del punto decimal, sin indicar ningún problema.
    • double ha 15.9 significativo dígitos decimales teniendo en cuenta los valores enteros solamente. La situación después del punto decimal es dependiente de valor.
  4. 5

    Desde decimal utiliza un factor de escala de múltiplos de 10, los números como 0.1 pueden ser representados exactamente. En esencia, el tipo decimal se representa como 1 /10 ^ 1, mientras que un double representaría esta como 104857 /2 ^ 20 (en realidad sería más como realmente gran número de /2 ^ 1023).

    Un decimal exactamente se puede representar cualquier base 10 valor con hasta 28 y 29 de dígitos significativos (como 0.1). Un double no puede.

    • Decimal no tiene 96 dígitos significativos. Dispone de 96 significativa bits. Decimal tiene alrededor de 28 dígitos significativos.
    • El idioma en el que hablan de el tipo decimal? O hacer todos los idiomas que admite este tipo de apoyo en exactamente la misma manera? Puede que desee especificar.
    • este post originalmente tenía el C# etiqueta, así que estamos hablando del Sistema.Decimal específicamente.
    • Uy, bien visto Jon! Corregidos. Adán, yo estoy hablando de C#, como por la pregunta. Hacer cualquier otra de las lenguas tienen un tipo llamado decimal?
    • Así, todos los idiomas que se basa en .RED, desde el Sistema.Decimal no es un único C# tipo, es un .Tipo de RED.
    • Me refería non-.NET los idiomas. Soy ignorante, inconsciente de los que tienen un nativo de base 10 tipo de punto flotante, pero no tengo ninguna duda de que existe.

  5. 4

    Mi entendimiento es que la mayoría de los sistemas financieros de express de la moneda usando números enteros, es decir, contando todo en centavos.

    De precisión doble de IEEE en realidad puede representar todos los números enteros exactamente en el rango de -2^53 a +2^53. (Del Hacker de las Delicias, pg. 262) Si sólo se usa la suma, la resta y la multiplicación, y mantener todo a enteros dentro de este rango, entonces usted debe ver sin pérdida de precisión. Me gustaría ser muy cautelosos a la hora de la división o de las operaciones más complejas, sin embargo.

    • Si usted sólo va a utilizar los números enteros, aunque, ¿por qué no utilizar un tipo entero, para empezar?
    • Je – int64_t pueden representar todos los números enteros exactamente en el rango de -2^63 a +2^63-1. Si utiliza sólo la suma, la resta y la multiplicación, y mantener todo a enteros dentro de este rango, entonces usted debe ver sin pérdida de precisión. Me gustaría ser muy cautelosos a la hora de división, sin embargo.
    • Algunos anticuados sistemas que son (por desgracia?) sigue en uso de la ayuda double, pero no son compatibles con 64 bits de tipo entero. Me atrevería a sugerir que la realización de cálculos como double, escala que cualquier semánticamente-requiere de redondeo siempre será para toda la unidad, es apto para ser el enfoque más eficaz.
  6. 2

    Utilizando el doble de cuando usted no sabe lo que está haciendo es inútil.

    «doble» puede representar un monto de un billón de dólares con un error de 1/90º de un centavo. Así que usted recibirá de alta precisión de los resultados. Se desea calcular cuánto cuesta poner un hombre en Marte y traerlo de vuelta con vida? doble estará bien.

    Pero con el dinero a menudo hay reglas muy específicas diciendo que un determinado cálculo debe dar un resultado determinado y no otro. Si se calcula una cantidad que es muy muy muy cerca de us $98.135, a continuación, con frecuencia, habrá una regla que determina si el resultado debe ser de $98.14 o $98.13 y debe siga esa regla y obtener el resultado que se requiere.

    Dependiendo de donde usted vive, el uso de enteros de 64 bits para representar centavos o monedas de un centavo o kopeks o lo que sea es la unidad más pequeña en su país se suelen funcionar bien. Por ejemplo, en la de 64 bits enteros que representan centavos puede representar valores de hasta 92,223 billones de dólares. 32 bits enteros son generalmente inadecuados.

  7. 0

    No un doble siempre tendrá errores de redondeo, el uso de «decimal» si usted está en .Neta…

    • Cuidado. Alguna representación de punto flotante tendrá errores de redondeo, decimal incluido. Es sólo que a decimal, se redondeará en formas que son intuitivos para los seres humanos (y por lo general, adecuadas para el dinero), y los binarios de punto flotante no. Pero para no financieros compuadora, doble a menudo es mucho, mucho mejor que el decimal, incluso en C#.
  8. -4

    Realidad de punto flotante doble es perfectamente adecuado para la representación de cantidades de dinero mientras usted elija una adecuada unidad.

    Ver http://www.idinews.com/moneyRep.html

    Así que es de punto fijo largo. Ya sea que consume entre 8 bytes, seguramente preferible a la de 16 consumida por un decimal elemento.

    Si o no funciona algo (es decir, los rendimientos de la espera y el resultado correcto) no es un asunto de la votación o de la preferencia del individuo. Una técnica que se trabaja o no.

    • La vinculación de un artículo que usted escribió que no está de acuerdo con décadas de prácticas comunes y de las opciones avanzadas que las de punto flotante no es adecuado para las transacciones financieras representaciones se va a tener que tener un poco más de copia de seguridad de una sola página.

Dejar respuesta

Please enter your comment!
Please enter your name here