comentario de David es correcta, pero insuficientemente fuerte. No hay garantía de que al hacer ese cálculo dos veces en el mismo programa se obtendrán los mismos resultados.
El C# especificación es extremadamente claro en este punto:
operaciones de punto flotante se pueden realizar con una mayor precisión que el tipo de resultado de la operación. Por ejemplo, algunas arquitecturas de hardware admiten un tipo de punto flotante "extendido" o "largo doble" con mayor rango y precisión que el tipo doble, e implícitamente realizan todas las operaciones de coma flotante con este tipo de precisión superior. Solo a un costo excesivo en rendimiento pueden tales arquitecturas de hardware realizar operaciones de punto flotante con menos precisión, y en lugar de requerir una implementación que pierda rendimiento y precisión, C# permite que se use un tipo de mayor precisión para todas las operaciones de coma flotante . Además de ofrecer resultados más precisos, esto rara vez tiene efectos mensurables. Sin embargo, en expresiones del formulario x * y/z
, donde la multiplicación produce un resultado que está fuera del rango doble, pero la división posterior devuelve el resultado temporal al rango doble, el hecho de que la expresión se evalúe en un formato de rango superior puede causar un resultado finito para ser producido en lugar de un infinito.
El compilador de C#, el jitter y el tiempo de ejecución todos tienen amplia LAttitude para darle resultados más precisos que los requeridos por la especificación, en cualquier momento, a su antojo - no son necesarios para elegir hacerlo de manera consistente y de hecho no lo hacen.
Si no te gusta, entonces no uses números de coma flotante binarios; usar decimales o racionales de precisión arbitraria.
No entiendo por qué la fundición a flotar en un método que devuelve flotador hace la diferencia que hace
Excelente punto.
Su programa de ejemplo demuestra cómo pequeños cambios pueden causar grandes efectos. Tenga en cuenta que en alguna versión del tiempo de ejecución, la conversión a flotación explícitamente da un resultado diferente que no hacerlo.Cuando seleccionas explícitamente flotar, el compilador de C# da una pista al tiempo de ejecución para decir "saca esto del modo de muy alta precisión si estás usando esta optimización". Como se especifica en la especificación, , esto tiene un costo de rendimiento potencial.
Que hacerlo llega a la "respuesta correcta" es simplemente un accidente feliz; se obtiene la respuesta correcta porque en este caso perdiendo precisión pasó a perderla en la dirección correcta.
¿Cómo es .net 4 diferente?
Usted pregunta cuál es la diferencia entre 3.5 y 4.0 tiempos de ejecución; la diferencia es claramente que en 4.0, el jitter elige ir a una mayor precisión en su caso particular, y el jitter 3.5 elige no hacerlo. Eso no quiere decir que esta situación sea imposible en 3.5; Ha sido posible en todas las versiones del tiempo de ejecución y en todas las versiones del compilador de C#. Acabas de encontrar un caso donde, en tu máquina, difieren en sus detalles. Pero el jitter tiene siempre permitido hacer esta optimización, y siempre lo ha hecho a su antojo.
El compilador C# también tiene todos los derechos para elegir realizar optimizaciones similares al calcular flotantes constantes en tiempo de compilación. Dos cálculos aparentemente idénticos en constantes pueden tener diferentes resultados dependiendo de los detalles del estado de tiempo de ejecución del compilador.
En general, su expectativa de que los números de punto flotante deberían tener las propiedades algebraicas de los números reales está completamente fuera de línea con la realidad; ellos no tienen esas propiedades algebraicas. Las operaciones de coma flotante no son ni siquiera asociativo; ciertamente no obedecen las leyes de los inversos multiplicativos, como parece esperar que lo hagan. Los números de coma flotante son solo una aproximación de la aritmética real; una aproximación lo suficientemente cercana para, por ejemplo, simular un sistema físico o calcular estadísticas de resumen, o algo por el estilo.
variables de coma flotante son, por definición, 100% exactas. Son números aproximados. http://msdn.microsoft.com/en-us/library/b1e65aza.aspx Vea también esta publicación: http://stackoverflow.com/questions/618535/what-is-the-difference-between-decimal-float -y-doble-en-c No hay garantía de que sean iguales en * cualquier * sabor del tiempo de ejecución. – David
Un enlace más útil: http://msdn.microsoft.com/en-us/library/ms187912.aspx – David
No obstante, es una pregunta interesante. Funcionalmente uno esperaría que estos métodos A y B realizaran la misma operación, incluso con la aproximación de coma flotante. Estoy interesado en escuchar la explicación. –