2008-12-04 27 views
5

Dado que Decimal.MaxValue = 79228162514264337593543950335mproblemas de redondeo decimal

¿Por qué la línea siguiente dame 7922816251426433759354395034M en la ventana local en lugar de 7922816251426433759354395033.5m como se esperaba?

Decimal target = Decimal.MaxValue/10m;

Respuesta

6

Sospecho que esto es un error del compilador, en realidad.

Aquí es un programa corto pero completo para mostrar por qué creo que:

using System; 

class Test 
{ 
    static void Main() 
    { 
     decimal constant = decimal.MaxValue/10m; 
     decimal calculated = decimal.MaxValue; 
     calculated /= 10m; 

     Console.WriteLine (constant); 
     Console.WriteLine (calculated);   
    } 
} 

Salida:

7922816251426433759354395034 
7922816251426433759354395033.5 

voy a cavar en la especificación para ver qué se dan garantías.

EDIT: En la especificación, Sección 7.18 reivindicaciones:

La evaluación en tiempo de compilación de expresiones constantes utiliza los mismos reglas como la evaluación de tiempo de ejecución de expresiones no constantes, excepto que donde la evaluación en tiempo de ejecución tendría lanzada una excepción, la evaluación en tiempo de compilación provoca un error en tiempo de compilación .

Claramente no es el caso aquí. Hmm.

EDITAR: He enviado a bug to Microsoft Connect. Veremos qué le sucede.

+0

Esta aserción fallan: Assert.IsTrue (Decimal.MaxValue/10m == 7922816251426433759354395033.5m); – izokurew

+0

Sí, eso es hacer un control constante. Básicamente, la aritmética constante del compilador tiene la culpa aquí, creo. –

0

supongo que porque está sobrepasando el valor de precisión máximo cuando estás dividiendo por 10. http://en.wikipedia.org/wiki/Arithmetic_precision

+0

No, la precisión es la misma, ya que estamos usando un tipo de decimal. Debería ser capaz de notar fácilmente que la división es por cero, mantener la mantisa igual y simplemente cambiar el exponente. Es perfectamente posible representar el resultado exacto como un decimal. –