Мой контекст
Я реализовал метод равенства(Object o) для объекта скорости (Vitesse здесь), что, когда он сталкивается с сравниваемым значением в м/с, когда оно само в км/ч (в примере), перед сравнением значений также помещается сравниваемое значение в км/ч. И я тестирую его в этом тесте, где он запускается последним оператором AssertEquals(...):
@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");
}
Моя проблема
Где-то в методе равенства возврат v == this.valeur.doubleValue() отвечает (правильно!) false, потому что из:
объекта this со значением 10,266940451745379 м/с
и o параметр для метода Equals со значением 36,96098562628337 км/ч
который следует считать равным после преобразования, он сравнивает в конечном итоге 10,26694045174538 км/ч с 10,266940451745379 км/ч... чьи четыре последних десятичных знака не равны.
Мой вопрос
В данном случае я мог бы сказать:
| 10.26694045174538 - 10.266940451745379 | < 0.001
Но мой метод равенства(Объект o), который сравнивает значения и сначала решает преобразовать их в другую единицу измерения, должен работать для любого диапазона значений...
Вывод из | 10.26694045174538 - 10.266940451745379 | < 0,001 верно.
Но что, если сравниваемые два числа были 0,0000005671226 и 0,0000005671425?
| 0.00000056722 - 0.00000056742 | < 0.001 тогда не имел бы смысла.
Я хотел бы знать, как на основе одного из сравниваемых значений я мог бы определить значение, которое следует присвоить правому члену моего неравенства.
Во втором примере это может быть:
| 0.00000056722 - 0.00000056742 | < 0.0000000001Вместо этого .
Сказано по-другому:
Как автоматизировать определение правильного значения c из значения a здесь:
| a - b | < c
чтобы быть уверенным, что эта проверка будет иметь смысл независимо от значения ?
Эпилог: решение, рад вашей помощи!
public boolean equals(Object o) {
if (o instanceof NotionMesurable notion) {
// Nous ne comparons pas le nom ni la description de la notion de base, car ce sont les valeurs qui nous intéressent.
// Si nous avons la même unité de mesure et la même valeur, nous sommes égaux avec la notion candidate.
if (this.uniteMesure.equals(notion.uniteMesure) && this.valeur.equals(notion.valeur)) {
return true;
}
// Mais si nous n'avons pas la même unité de mesure que notre candidat, nous pouvons tenter convertir sa valeur dans la nôtre, pour voir si nous sommes égaux.
// À la condition notre unité de mesure et celle canditate soient compatibles.
try {
Number converti = notion.en(notion.uniteMesure(), this.uniteMesure());
if (converti instanceof Double v && this.valeur instanceof Double) {
double t = this.valeur.doubleValue();
if (v == t) {
return true;
}
if (v == 0 || t == 0) {
return Math.abs(v - t) < 0.001;
}
else {
return Math.abs(v > t ? v / t : t / v) < 1.001;
}
}
if (converti instanceof BigDecimal v && this.valeur instanceof BigDecimal) {
double t = this.valeur.doubleValue();
if (v.equals(this.valeur)) {
return true;
}
if (v.doubleValue() == 0 || t == 0) {
return Math.abs(v.doubleValue() - t) < 0.001;
}
else {
return Math.abs(v.doubleValue() > t ? v.doubleValue() / t : t / v.doubleValue()) < 1.001;
}
}
if (converti instanceof Float v && this.valeur instanceof Float) {
float t = this.valeur.floatValue();
if (v == t) {
return true;
}
if (v == 0 || t == 0) {
return Math.abs(v - t) < 0.001;
}
else {
return Math.abs(v > t ? v / t : t / v) < 1.001;
}
}
if (converti instanceof Long v && this.valeur instanceof Long) {
return v == this.valeur.longValue();
}
if (converti instanceof Integer v && this.valeur instanceof Integer) {
return v == this.valeur.intValue();
}
if (converti instanceof Short v && this.valeur instanceof Short) {
return v == this.valeur.shortValue();
}
if (converti instanceof Byte v && this.valeur instanceof Byte) {
return v == this.valeur.byteValue();
}
}
catch(UnitesDeMesuresIncomparablesException e) {
return false;
}
return false;
}
// S'il nous est donné une valeur et pas une notion, comparer directement la valeur
if (o instanceof Double v && this.valeur instanceof Double) {
return v == this.valeur.doubleValue();
}
if (o instanceof Long v && this.valeur instanceof Long) {
return v == this.valeur.longValue();
}
if (o instanceof Integer v && this.valeur instanceof Integer) {
return v == this.valeur.intValue();
}
if (o instanceof BigDecimal v && this.valeur instanceof BigDecimal) {
return v.equals(this.valeur);
}
if (o instanceof Float v && this.valeur instanceof Float) {
return v == this.valeur.floatValue();
}
if (o instanceof Short v && this.valeur instanceof Short) {
return v == this.valeur.shortValue();
}
if (o instanceof Byte v && this.valeur instanceof Byte) {
return v == this.valeur.byteValue();
}
return false;
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... und-method
Как систематизировать проверку «а вполне равно b» (либо методом округления, либо | a - b | ~ 0) для любого значения a? ⇐ JAVA
Программисты JAVA общаются здесь
1770088215
Anonymous
Мой контекст
Я реализовал метод равенства(Object o) для объекта скорости (Vitesse здесь), что, когда он сталкивается с сравниваемым значением в м/с, когда оно само в км/ч (в примере), перед сравнением значений также помещается сравниваемое значение в км/ч. И я тестирую его в этом тесте, где он запускается последним оператором AssertEquals(...):
@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");
}
Моя проблема
Где-то в методе равенства возврат v == this.valeur.doubleValue() отвечает (правильно!) false, потому что из:
объекта this со значением 10,266940451745379 м/с
и o параметр для метода Equals со значением 36,96098562628337 км/ч
который следует считать равным после преобразования, он сравнивает в конечном итоге 10,26694045174538 км/ч с 10,266940451745379 км/ч... чьи четыре последних десятичных знака не равны.
Мой вопрос
В данном случае я мог бы сказать:
| 10.26694045174538 - 10.266940451745379 | < 0.001
Но мой метод равенства(Объект o), который сравнивает значения и сначала решает преобразовать их в другую единицу измерения, должен работать для любого диапазона значений...
Вывод из | 10.26694045174538 - 10.266940451745379 | < 0,001 верно.
Но что, если сравниваемые два числа были 0,0000005671226 и 0,0000005671425?
| 0.00000056722 - 0.00000056742 | < 0.001 тогда не имел бы смысла.
Я хотел бы знать, как на основе одного из сравниваемых значений я мог бы определить значение, которое следует присвоить правому члену моего неравенства.
Во втором примере это может быть:
| 0.00000056722 - 0.00000056742 | < 0.0000000001Вместо этого .
Сказано по-другому:
Как автоматизировать определение правильного значения c из значения a здесь:
| a - b | < c
чтобы быть уверенным, что эта проверка будет иметь смысл независимо от значения ?
Эпилог: решение, рад вашей помощи!
public boolean equals(Object o) {
if (o instanceof NotionMesurable notion) {
// Nous ne comparons pas le nom ni la description de la notion de base, car ce sont les valeurs qui nous intéressent.
// Si nous avons la même unité de mesure et la même valeur, nous sommes égaux avec la notion candidate.
if (this.uniteMesure.equals(notion.uniteMesure) && this.valeur.equals(notion.valeur)) {
return true;
}
// Mais si nous n'avons pas la même unité de mesure que notre candidat, nous pouvons tenter convertir sa valeur dans la nôtre, pour voir si nous sommes égaux.
// À la condition notre unité de mesure et celle canditate soient compatibles.
try {
Number converti = notion.en(notion.uniteMesure(), this.uniteMesure());
if (converti instanceof Double v && this.valeur instanceof Double) {
double t = this.valeur.doubleValue();
if (v == t) {
return true;
}
if (v == 0 || t == 0) {
return Math.abs(v - t) < 0.001;
}
else {
return Math.abs(v > t ? v / t : t / v) < 1.001;
}
}
if (converti instanceof BigDecimal v && this.valeur instanceof BigDecimal) {
double t = this.valeur.doubleValue();
if (v.equals(this.valeur)) {
return true;
}
if (v.doubleValue() == 0 || t == 0) {
return Math.abs(v.doubleValue() - t) < 0.001;
}
else {
return Math.abs(v.doubleValue() > t ? v.doubleValue() / t : t / v.doubleValue()) < 1.001;
}
}
if (converti instanceof Float v && this.valeur instanceof Float) {
float t = this.valeur.floatValue();
if (v == t) {
return true;
}
if (v == 0 || t == 0) {
return Math.abs(v - t) < 0.001;
}
else {
return Math.abs(v > t ? v / t : t / v) < 1.001;
}
}
if (converti instanceof Long v && this.valeur instanceof Long) {
return v == this.valeur.longValue();
}
if (converti instanceof Integer v && this.valeur instanceof Integer) {
return v == this.valeur.intValue();
}
if (converti instanceof Short v && this.valeur instanceof Short) {
return v == this.valeur.shortValue();
}
if (converti instanceof Byte v && this.valeur instanceof Byte) {
return v == this.valeur.byteValue();
}
}
catch(UnitesDeMesuresIncomparablesException e) {
return false;
}
return false;
}
// S'il nous est donné une valeur et pas une notion, comparer directement la valeur
if (o instanceof Double v && this.valeur instanceof Double) {
return v == this.valeur.doubleValue();
}
if (o instanceof Long v && this.valeur instanceof Long) {
return v == this.valeur.longValue();
}
if (o instanceof Integer v && this.valeur instanceof Integer) {
return v == this.valeur.intValue();
}
if (o instanceof BigDecimal v && this.valeur instanceof BigDecimal) {
return v.equals(this.valeur);
}
if (o instanceof Float v && this.valeur instanceof Float) {
return v == this.valeur.floatValue();
}
if (o instanceof Short v && this.valeur instanceof Short) {
return v == this.valeur.shortValue();
}
if (o instanceof Byte v && this.valeur instanceof Byte) {
return v == this.valeur.byteValue();
}
return false;
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79880817/how-to-systematise-a-checking-of-a-quite-equals-to-b-either-with-round-method[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия