¿Por qué debería usar el complemento de 2 para comparar dos dobles en lugar de comparar sus diferencias con un valor épsilon?

Hace referencia a aquí y aquí ... ¿Por qué debería usar complemento de dos sobre un método épsilon? Parece que el método épsilon sería lo suficientemente bueno para la mayoría de los casos.


Update: I'm purely looking for a theoretical reason why you'd use one over the other. I've always used the epsilon method.

¿Alguien ha usado la comparación del complemento de 2 con éxito? ¿Por qué? ¿Por qué no?

0
agregado editado
Puntos de vista: 1

6 Respuestas

Oskar tiene razón. No te metas con esto a menos que realmente necesites ese rendimiento.

Y tu no. Si estuviera en la situación que lo hizo, no habría necesitado hacer la pregunta, ya lo sabría. Si crees que lo haces, entonces no lo haces. Tus problemas de rendimiento están en otra parte. Solo usa la versión legible.

0
agregado

El método de los bits podría ser más rápido. Digo que sí, porque en procesadores modernos (multinúcleo, altamente canalizados) a menudo es imposible adivinar qué es realmente más rápido. Codifique la implementación más sencilla y más correcta, luego mida y luego modifique.

0
agregado

Cuando se trata de velocidad, siga estas reglas:

  1. Si no eres un desarrollador con mucha experiencia, no optimices.
  2. Si es un desarrollador experimentado, no optimice aún.

Haz el método más fácil.

Alex

0
agregado
¿Qué tiene esto que ver con lo que estoy preguntando? Quiero saber por qué usarías un enfoque sobre otro, no si optimizarías algo.
agregado el autor Steve Duitsman, fuente

el segundo enlace al que hace referencia menciona un artículo que tiene una descripción bastante larga del problema:

http://www.cygnus-software.com/papers/comparingfloats/comparingfloats. htm

pero a menos que estés ajustando el rendimiento, me quedaría con épsilon para que la gente pueda depurar tu código

0
agregado
¿Tan corta respuesta ... el rendimiento es mejor cuando se compara con épsilon?
agregado el autor Steve Duitsman, fuente
Estoy de acuerdo contigo. Si nada más, la legibilidad debería ser mi primera preocupación.
agregado el autor Steve Duitsman, fuente
tenga en cuenta que el rendimiento puede ser peor utilizando el método de bits enteros, ya que mover cadenas de bits entre registros de coma flotante y enteros no es una operación rápida (dependiendo del chip y el conjunto de instrucciones utilizados). Lo evitaría a menos que estés absolutamente seguro de que necesitas el rendimiento adicional, y no puedes obtenerlo (por ejemplo) simplemente eligiendo un épsilon absoluto inteligentemente.
agregado el autor Eamon Nerbonne, fuente
No lo se No usaría nada tan complejo para una comparación a menos que la comparación de números fuera la parte principal de mi aplicación. Solo imagina el tiempo en que depuraron un simple error tipográfico ...
agregado el autor Oskar, fuente

En resumen, cuando se comparan dos carrozas con orígenes desconocidos, es casi imposible elegir un épsilon que sea válido.

Por ejemplo:

¿Qué es un buen épsilon cuando se compara la distancia en millas entre Atlanta GA, Dallas TX y algún lugar en Ohio?

¿Qué es un buen épsilon cuando comparo la distancia en millas entre mi pie izquierdo, mi pie derecho y la computadora debajo de mi escritorio?

EDITAR:

Ok, estoy recibiendo un buen número de personas que no entienden por qué no sabrías qué es tu épsilon.

En los viejos tiempos de la ciencia, escribí dos programas que funcionaban con NeverWinter Nights (un juego hecho por BioWare). Uno de los programas tomó un modelo binario y lo convirtió a ASCII. El otro programa tomó un modelo ASCII y lo compiló en binario. Una de las pruebas que escribí fue tomar todos los modelos binarios de BioWare, descompilarlos en ASCII y luego volver a binarios. Luego comparé mi versión binaria con la original de BioWare. Uno de los problemas durante la comparación fue lidiar con algunas de las pequeñas variaciones en los valores de coma flotante. Entonces, en lugar de generar un montón de diferentes EPSILONS para cada tipo de número de coma flotante (vértice, normal, etc.), quería usar algo como este complemento de dos en comparación. Evitando así todo el problema múltiple de EPSILON.

El mismo tipo de problema puede aplicarse a cualquier tipo de software que procese datos de terceros y luego necesite validar sus resultados con el original. En estos casos, es posible que ni siquiera sepa qué representan los valores de coma flotante, solo tiene que compararlos. Nos encontramos con este problema con nuestro software de automatización industrial.

EDITAR:

LOL, esto ha sido votado por diferentes personas.

Voy a reducir el problema a esto, dados dos números de coma flotante arbitrarios , ¿cómo se decide qué epsilon usar? No puedes.

¿Cómo se puede comparar 1e23 y 1.0001e23 con un epsilon y aún comparar 1e-23 y 5.2e-23 con el mismo épsilon? Claro, puedes hacer algunos trucos epsilon dinámicos, pero ese es el punto completo de la comparación de enteros (que NO requiere que los enteros sean exactos).

La comparación de números enteros es capaz de comparar dos flotantes usando un épsilon relativo a la magnitud de los números.

EDITAR

Steve, veamos lo que dijiste en los comentarios:

"Pero sabes lo que la igualdad significa para ti ... Por lo tanto, deberías ser capaz de encontrar un épsilon apropiado".

Da vuelta a esta afirmación para decir:

"Si sabes lo que la igualdad significa para ti, entonces deberías ser capaz de encontrar un épsilon apropiado".

Todo lo que quiero decir es que hay aplicaciones en las que no sabemos qué significa igualdad en el sentido absoluto, así que tenemos que recurrir a una comparación relativa, que es lo que intenta la versión entera.

0
agregado
Pero sabes lo que la igualdad significa para ti ... y tu código es el que los compara. Por lo tanto, debería poder encontrar un épsilon apropiado.
agregado el autor Steve Duitsman, fuente
Epsilon trabaja en el dominio del problema, si está escribiendo un mensaje de texto para obtenerlo de Dalls-Atlanta, el épsilon es la incertidumbre en su GPS
agregado el autor Martin Beckett, fuente
Eso es cierto, pero mi punto es que cuando no tienes un marco de referencia en cuanto a los orígenes de las carrozas, elegir un épsilon sería muy difícil.
agregado el autor Torlack, fuente

Using any method that compares bitwise will result in trouble when fractions are represented by approximations. All floating point numbers with fractions that are not denominated in powers of two (1/2, 1/4, 1/8, 1/65536, &c) are approximated. So, of course, are all irrational numbers.

flotante tercero = 1/3; flotante dos = 2.0; flotante another_two = third * 6.0; si (dos! = otro_dos)    print ("Aproximación! \ n");

La única vez que funcionaría la comparación bit a bit sería cuando deriva los números de punto flotante exactamente de la misma manera o son representaciones exactas (números enteros, potencias de fracción de dos). Incluso entonces, puede haber múltiples representaciones de algunos números, aunque nunca he visto esto en un sistema en funcionamiento.

0
agregado
Yo tampoco, por eso tengo curiosidad.
agregado el autor Steve Duitsman, fuente