Comparando valores dobles en C#

Resuelto stack_pointer is EXTINCT asked hace 15 años • 18 respuestas

Tengo una doublevariable llamada x. En el código, xse le asigna un valor de 0.1y lo verifico en una declaración 'si' comparando xy0.1

if (x==0.1)
{
----
}

Lamentablemente no entra en el ifestado de cuenta.

  1. ¿Debo usar Doubleo double?

  2. ¿Cuál es la razón detrás de esto? ¿Puedes sugerir una solución para esto?

Aceptado

Es un problema estándar debido a cómo la computadora almacena valores de punto flotante. Busque aquí "problema de punto flotante" y encontrará toneladas de información.

En resumen, un flotador/doble no puede almacenar 0.1con precisión. Siempre estará un poco apagado.

Puedes intentar usar el decimaltipo que almacena números en notación decimal. Así 0.1será representable con precisión.


Querías saber el motivo:

Float/double se almacenan como fracciones binarias, no fracciones decimales. Para ilustrar:

12.34en notación decimal (lo que usamos) significa

1 * 10 1 + 2 * 10 0 + 3 * 10 -1 + 4 * 10 -2

La computadora almacena números de coma flotante de la misma manera, excepto que usa base 2: 10.01significa

1 * 2 1 + 0 * 2 0 + 0 * 2 -1 + 1 * 2 -2

Ahora bien, probablemente sepas que hay algunos números que no se pueden representar completamente con nuestra notación decimal. Por ejemplo, 1/3en notación decimal es 0.3333333…. Lo mismo ocurre en notación binaria, excepto que los números que no se pueden representar con precisión son diferentes. Entre ellos está el número 1/10. En notación binaria, eso es 0.000110011001100….

Dado que la notación binaria no puede almacenarlo con precisión, se almacena de forma redondeada. De ahí tu problema.

Vilx- avatar Sep 09 '2009 10:09 Vilx-

doubley Doubleson iguales ( doublees un alias de Double) y se pueden usar indistintamente.

El problema al comparar un valor doble con otro valor es que los dobles son valores aproximados, no valores exactos. Entonces, cuando lo configura, xen 0.1realidad puede almacenarse como 0.100000001algo así.

En lugar de verificar la igualdad, debe verificar que la diferencia sea menor que una diferencia mínima definida (tolerancia). Algo como:

if (Math.Abs(x - 0.1) < 0.0000001)
{
    ...
}
Rune Grimstad avatar Sep 09 '2009 10:09 Rune Grimstad

Necesitas una combinación de Math.Abson X-Yy a valuepara comparar.

Puede utilizar el siguiente método de extensión

public static class DoubleExtensions
    {
        const double _3 = 0.001;
        const double _4 = 0.0001;
        const double _5 = 0.00001;
        const double _6 = 0.000001;
        const double _7 = 0.0000001;

        public static bool Equals3DigitPrecision(this double left, double right)
        {
            return Math.Abs(left - right) < _3;
        }

        public static bool Equals4DigitPrecision(this double left, double right)
        {
            return Math.Abs(left - right) < _4;
        }

        ...

Dado que rara vez se llaman métodos en doble, excepto que ToStringcreo que es una extensión bastante segura.

Entonces puedes comparar xy ydarle me gusta.

if(x.Equals4DigitPrecision(y))

Valentin Kuzub avatar Oct 28 '2011 02:10 Valentin Kuzub