2010-06-08 15 views
16

¿Hay alguna razón por la que un C# System.Decimal recuerde el número de ceros finales con los que se ingresó? Véase el siguiente ejemplo:¿Por qué un C# System.Decimal recuerda los ceros al final?

public void DoSomething() 
{ 
    decimal dec1 = 0.5M; 
    decimal dec2 = 0.50M; 
    Console.WriteLine(dec1);   //Output: 0.5 
    Console.WriteLine(dec2);   //Output: 0.50 
    Console.WriteLine(dec1 == dec2); //Output: True 
} 

los decimales se clasifican como iguales, aún dec2 recuerda que se ha introducido con un cero adicional. ¿Cuál es la razón/propósito para esto?

Respuesta

12

Puede ser útil para representar un número incluyendo su exactitud - así 0.5m podrían utilizarse para significar "cualquier cosa entre 0,45 m y 0,55 m" (con límites apropiados) y 0.50m podrían utilizarse para significar "nada entre 0.495 my 0.545 m ".

Sospecho que la mayoría de los desarrolladores de realmente no usan esta funcionalidad, pero puedo ver cómo puede ser útil a veces.

creo que esta capacidad llegó por primera vez en .NET 1.1, por cierto - Creo decimales en 1.0 siempre eran efectivamente normalizado.

+2

Por las razones explicadas, 0.5 y 0.50 * tienen * información diferente. La precisión es ** muy ** relevante en algunos campos, a saber, las matemáticas y la química. – ANeves

+0

Esa sería una buena teoría, excepto que la cantidad de dígitos devueltos por las operaciones de la división no tiene nada que ver con la cantidad de dígitos en el divisor o dividendo. Para la mayoría de las situaciones que requieren multiplicación o división, parecería que 'Decimal' debería ofrecer un método para multiplicar por' Doble', con el resultado redondeado a un nivel de precisión específico; si el resultado no puede adaptarse a tanta precisión, lanza una excepción. De lo contrario, 'Decimal' pierde sus ventajas semánticas frente a los valores de escala hasta 100 (o el número de subdivisiones por unidad de moneda) y el uso de' Double'. – supercat

+0

@supercat: Hmm ... tienes razón sobre la parte de la división, sin duda. Todavía podría ser que la teoría es la capacidad de poder representar un número y su precisión, pero la práctica es que no está bien implementado para la aritmética. (Todavía podría ser útil al propagar datos de otra fuente, por supuesto.) –

2

Los decimales representan valores decimales de precisión fija. El valor literal 0.50M tiene la precisión de dos decimales incrustada, por lo que la variable decimal creada recuerda que tiene un valor de dos decimales. El comportamiento es completamente por diseño.

La comparación de los valores es una comprobación de igualdad numérica exacta de los valores, por lo que aquí, los ceros finales no afectan el resultado.

+4

La "precisión fija" podría ser engañosa aquí. Es un tipo de coma flotante, como 'flotante 'y' doble' - es solo que el punto es un punto decimal en lugar de un punto binario (y los límites son diferentes). –

2

Creo que se hizo para proporcionar una mejor representación interna de los valores numéricos recuperados de las bases de datos. Los motores Dbase tienen un largo historial de almacenamiento de números en formato decimal (evitando errores de redondeo) con una especificación explícita de la cantidad de dígitos del valor.

comparar el SQL Server decimal and numeric column types por ejemplo.

+0

Está mapeando específicamente entre el tipo decimal de .NET y el tipo decimal del servidor SQL que pueden crear problemas. Si usa 'decimal (19,6)' en la base de datos, y 'decimal' en C#, y luego el usuario ingresa' 0.5M', cuando lo almacena y lo recupera de la base de datos, obtendrá '0.500000 ', que es más precisión que el usuario ingresado. Debe almacenar la precisión en un campo separado o imponer una precisión establecida en el campo para todos los valores. –

Cuestiones relacionadas