variable que programacion float c# .net compiler-bug

c# - float - que es int en programacion



valor de ''const float'' diferente de ''float'' cuando se convierte a ''int'' en C# (2)

¿Alguno de ustedes puede explicar por qué sucede esto?

static void Main() { const float xScaleStart = 0.5f; const float xScaleStop = 4.0f; const float xScaleInterval = 0.1f; const float xScaleAmplitude = xScaleStop - xScaleStart; const float xScaleSizeC = xScaleAmplitude / xScaleInterval; float xScaleSize = xScaleAmplitude / xScaleInterval; Console.WriteLine(">const float {0}, (int){1}", xScaleSizeC, (int)xScaleSizeC); Console.WriteLine("> float {0}, (int){1}", xScaleSize, (int)xScaleSize); Console.ReadLine(); }

Salida:

>const float 35, (int)34 > float 35, (int)35

Sé que la representación binaria de 0.1 es en realidad 0.09999990463256835937, aunque ¿por qué ocurre esto usando ''const float'' y no con ''float''? ¿Esto se considera un error de compilación?

Para el registro, el código se compila en:

private static void Main(string[] args) { float xScaleSize = 35f; Console.WriteLine(">const float {0}, (int){1}", 35f, 34); Console.WriteLine("> float {0}, (int){1}", xScaleSize, (int)xScaleSize); Console.ReadLine(); }


El "Por qué" de esto se reducirá básicamente al hecho de que frecuentemente, cuando se trabaja con datos float , se puede usar una representación interna que tenga más precisión que la especificada para float o double . Esto se cubre explícitamente en la Especificación del Sistema de Ejecución Virtual (VES) (sección 12 de la Partición I ):

los números de coma flotante se representan utilizando un tipo de punto flotante interno. En cada caso, el tipo nominal de la variable o expresión es float32 o float64 , pero su valor puede representarse internamente con rango y / o precisión adicionales.

Y luego tenemos:

El uso de una representación interna que es más ancha que float32 o float64 puede causar diferencias en los resultados computacionales cuando un desarrollador realiza modificaciones aparentemente no relacionadas a su código, cuyo resultado puede ser que un valor se derrame de la representación interna (p. Ej., En un registrarse) a una ubicación en la pila.

Ahora, de acuerdo con la especificación del lenguaje C # :

La evaluación en tiempo de compilación de expresiones constantes utiliza las mismas reglas que la evaluación en tiempo de ejecución de expresiones no constantes, excepto que cuando la evaluación en tiempo de ejecución arrojaría una excepción, la evaluación en tiempo de compilación provoca un error en tiempo de compilación.

Pero como observamos anteriormente, las reglas realmente permiten que se use más precisión a veces, y cuando se utiliza esta precisión mejorada, en realidad no está bajo nuestro control directo.

Y, obviamente, en diferentes circunstancias, los resultados podrían haber sido exactamente lo opuesto a lo que observó: el compilador puede haber bajado a una menor precisión y el tiempo de ejecución podría haber mantenido una mayor precisión en su lugar.


No puedo decir que esta es una pregunta duplicada, ya que aquí -> Eric Postpischil comment

explicó algo muy similar con respecto a int y const int.

La idea principal es que la división de dos constantes sea calculada por el compilador antes de generar el código y no en tiempo de ejecución, PERO en este caso específico cada vez que el compilador hace esto realiza los cálculos en doble formato. Por lo tanto, el xScaleSizeC es básicamente igual a 34.9999 ... por lo que cuando se lanza en tiempo de ejecución a int se convierte en 34.