How to systematise a checking of "a quite equals to b" (either with round method or | a - b | ~ 0) for any value of a?

2 days ago 3
ARTICLE AD BOX

My context

I have implemented an equals(Object o) method for a speed object (Vitesse here) that when it faces a comparand being in m/s when it is itself in km/h (in example) puts the comparand in km/h too before comparing the values. And I'm testing it in this test where it is triggered by the last assertEquals(...) statement:

@Test @DisplayName("Ex E1, Benson Ch. 3") void ex_Benson_Ch3_E1() { LOGGER.info("Asafa Powell (Jamaïque) court 100m en 9.74s. Quelle est sa vitesse moyenne ?\nSerait-il en infraction dans une zone scolaire où la vitesse est limitée à 30 km/h ?"); Vitesse vitesseMoyenne = new Vitesse(100, 9.74); // Par défaut, en mètres secondes assertEquals(10.3, vitesseMoyenne.vitesse(), 0.1, "La vitesse moyenne du coureur n'est pas la bonne, en m/s"); // Vérifier les conversions, étape par étape Vitesse v1 = new Vitesse(vitesseMoyenne); v1.convertir(KILOMETRE); assertEquals(0.0103, v1.vitesse(), 0.1, "La vitesse moyenne du coureur n'est pas la bonne, en km/s"); assertEquals("km/s", v1.uniteMesure().symbole(), "La vitesse moyenne du coureur n'est pas exprimée en km/s"); v1.convertir(HEURE); assertEquals(36.961, v1.vitesse(), 0.001, "La vitesse moyenne du coureur n'est pas la bonne, en km/h (A)"); assertEquals("km/h", v1.uniteMesure().symbole(), "La vitesse moyenne du coureur n'est pas exprimée en km/h (A)"); // Vérifier la conversion d'un seul tenant Vitesse v2 = new Vitesse(vitesseMoyenne); v2.convertir(KILOMETRE, HEURE); assertEquals(36.961, v2.vitesse(), 0.001, "La vitesse moyenne du coureur n'est pas la bonne, en km/h (B)"); assertEquals("km/h", v2.uniteMesure().symbole(), "La vitesse moyenne du coureur n'est pas exprimée en km/h (B)"); if (v2.vitesse() > 36.0) { LOGGER.info("Il serait bien en infraction dans une zone limitée à 30 km/h !"); } else { Assertions.fail("Il aurait dû être en infraction dans une zone limitée à 30 km/h"); } // La vitesse moyenne, qui est restée en m/s, doit être égale à celle en km/h. assertEquals(vitesseMoyenne, v2, "La vitesse moyenne du coureur, en m/s, doit être la même que celle en km/h, car une conversion est attendue durant la comparaison"); }

My problem

Somewhere in the equals method, a return v == this.valeur.doubleValue() responds (correctly!) false because from:
the this object valued 10.266940451745379 m/s
and an o parameter for the equals method valued 36.96098562628337 km/h
that should be considered equals after conversion, it is comparing eventually 10.26694045174538 km/h to 10.266940451745379 km/h... whose the four last decimals aren't equal.


My question

I could say in this case:
| 10.26694045174538 - 10.266940451745379 | < 0.001

But my equals(Object o) that compares values and decides to convert one to another unit of measure first, is supposed to work for any range of values...

Conclude from | 10.26694045174538 - 10.266940451745379 | < 0.001 is correct.

But what if the two numbers compared were 0.0000005671226 and 0.0000005671425?
| 0.00000056722 - 0.00000056742 | < 0.001 wouldn't then have a sense.

I would like to know how from one of the comparands, I might decide the value to put on the right member of my inequality.
In this second example, it could be:
| 0.00000056722 - 0.00000056742 | < 0.0000000001 instead.

Said another manner: How to automate the determination of the proper c value from a a value here:
| a - b | < c
in order to be sure that this checking will have a sense whatever the value of a?

Read Entire Article