que punto programacion normalizada mantisa flotante float ejemplos binario java ant findbugs

java - programacion - punto flotante ieee 754 ejemplos



Prueba de igualdad de punto flotante.(FE_FLOATING_POINT_EQUALITY) (3)

Estoy usando Findbugs en una secuencia de comandos ANT y no puedo encontrar la manera de corregir dos de mis errores. He leído la documentación, pero no entiendo. Aquí están mis errores y el código que los acompaña:

Error 1: Prueba de igualdad de punto flotante. (FE_FLOATING_POINT_EQUALITY)

private boolean equals(final Quantity other) { return this.mAmount == convertedAmount(other); }

Error 2: EQ_COMPARETO_USE_OBJECT_EQUALS

public final int compareTo(final Object other) { return this.description().compareTo(((Decision) other).description()); }

He leído la documentación para el problema de ComparesTo que dice

Se recomienda encarecidamente, pero no es estrictamente obligatorio que (x.compareTo (y) == 0) == (x.equals (y)). En términos generales, cualquier clase que implemente la interfaz Comparable y viole esta condición debe indicar claramente este hecho. El lenguaje recomendado es "Nota: esta clase tiene un orden natural que es inconsistente con los iguales".

Y también los documentos sobre la igualdad de punto flotante.

Esta operación compara dos valores de punto flotante para la igualdad. Debido a que los cálculos de punto flotante pueden implicar redondeo, los valores flotantes y dobles calculados pueden no ser exactos. Para los valores que deben ser precisos, como los valores monetarios, considere usar un tipo de precisión fija como BigDecimal. Para valores que no necesitan ser precisos, considere comparar la igualdad dentro de algún rango, por ejemplo: if (Math.abs (x - y) <.0000001). Vea la Especificación del lenguaje Java, sección 4.2.4.

Aunque no lo entiendo. Alguien puede ayudarme porfavor?


No estoy de acuerdo con las respuestas anteriores. Equals y compareTo son el lugar equivocado para introducir epsilons en comparaciones de punto flotante.

Los valores de punto flotante se pueden comparar exactamente por igual y compareTo, simplemente usando el operador "==".
Si su aplicación usa flotadores que son el resultado de un cálculo , necesita comparar estos valores con el enfoque épsilon, debería hacerlo solo en ese lugar donde sea necesario. Por ejemplo, en un método de intersección de líneas matemáticas.
Pero no en iguales y compara.

Esta advertencia es muy engañosa. Significa que comparar dos flotadores en los que al menos una es el resultado de un cálculo podría dar un resultado inesperado. Sin embargo, a menudo tales flotantes, para comparar, no son el resultado de un cálculo, como

static final double INVALID_VALUE = -99.0; if (f == INVALID_VALUE)

donde f se inicializa con INVALID_VALUE, en java siempre funcionará perfectamente. Pero Findbugs y Sonarcube todavía se quejarán.

Así que solo agregue un filtro de ignorar a los errores de búsqueda, asumiendo que tiene dos clases MyPoint2D y Myrectangle2D

<Match> <OR> <Class name="~.*/.MyPoint2D" /> <Class name="~.*/.MyRectangle2D" /> </OR> <Bug code="FE" /> <Justification author="My Name" /> <Justification text="Floating point equals works (here)." /> </Match>


Para la advertencia de punto flotante, debe tener en cuenta que los flotadores son un tipo inexacto . Una referencia estándar que se da para esto (que vale la pena leer una vez quizás) es:

Lo que todo científico informático debe saber sobre la aritmética de punto flotante por David Goldberg.

Debido a que los flotantes no son valores exactos, incluso si se ven iguales cuando se redondean a unos pocos decimales, pueden diferir muy ligeramente y no coincidir.

La interfaz comparable espera un cierto comportamiento de su implementador; La advertencia le indica que no se está adhiriendo a eso y que está ofreciendo acciones sugeridas.


Problema 1:

Para el problema FE_FLOATING_POINT_EQUALITY, no debe comparar dos valores flotantes directamente con el operador == , ya que, debido a pequeños errores de redondeo, los valores pueden ser semánticamente "iguales" para su aplicación, incluso si la condición value1 == value2 no se cumple. .

Para arreglar esto, modifique su código de la siguiente manera:

private boolean equals(final Quantity other) { return (Math.abs(this.mAmount - convertedAmount(other)) < EPSILON); }

Donde EPSILON es una constante que debe definir en su código y representa pequeñas diferencias que son aceptables para su aplicación, por ejemplo, .0000001.

Problema 2:

Para el problema EQ_COMPARETO_USE_OBJECT_EQUALS: se recomienda encarecidamente que siempre que x.compareTo(y) devuelva cero, x.equals(y) deba ser true . En su código, ha implementado compareTo , pero no ha anulado los equals , por lo que está heredando la implementación de equals de Object , y no se cumple la condición anterior.

Para solucionar esto, anular equals (y tal vez hashCode ) en su clase, de modo que cuando x.compareTo(y) devuelva 0, entonces x.equals(y) devolverá true .