Допустим, я пишу физический движок с обнаружением столкновений, используя поплавки. Один из методов может состоять в том, чтобы проверить, пересекаются или соприкасаются два физических объекта.
class PhysicsObject {
Vector3f position;
[...]
public void isIntersecting(PhysicsObject otherObject) {
boolean isTouchingOrIntersecting = [do calculations];
return isTouchingOrIntersecting;
}
}
Для самой симуляции точность с плавающей запятой (даже при использовании с плавающей запятой) достаточно хороша, потому что любые неточности не будут видны/заметны (и будут немедленно исправлены на следующем этапе симуляции).
Но как мне написать свои модульные тесты, особенно для пограничных случаев? Я могу написать тесты с двумя удаленными объектами и двумя явно пересекающимися объектами, но как насчет того, чтобы они точно соприкасались? В зависимости от значений с плавающей запятой метод может возвращать true или false в зависимости от любого внешнего условия (компилятор, архитектура и т. д.).
Или я должен сказать, что не важно, какой результат возвращает метод в этом граничном случае, и поэтому нет смысла писать модульный тест для этого случая?
Когда возвращаемое значение метода снова является числом с плавающей запятой, становится ясно, что я должен использовать относительные ошибки и эпсилоны. Но я использую эту проблему обнаружения столкновений в качестве примера для всего класса подобных проблем, когда плавающие точки преобразуются в какой-то "точный" (логический, целочисленный) результат, и как их тестировать (в контексте 3D-графики/физики). код).