Соответствующее поведение, чтобы предотвратить деление на ноль

Нас попросили спроектировать класс Vector3D, используя память в стеке. Мне нужно разделить вектор на скаляр, но что является наиболее подходящим для предотвращения деления на ноль? Я мог бы бросить исключение? Я не хочу возвращать Vector3D (0,0,0), потому что это предполагает, что операция прошла успешно, хотя на самом деле это не так.

Vector3DStack Vector3DStack::operator / (float s) const
{
if (s == 0)
{
// How should I handle division by zero?
// Method is expecting a Vector3DStack to be returned.

}

return Vector3DStack(x / s, y / s, z / s);
}

0

Решение

Вы обязательно должны выбросить исключение. Это то, для чего предназначены исключения — чтобы указать исключительные обстоятельства в вашем коде. На самом деле вы также можете разрешить небольшой допуск около нуля, например:

Vector3DStack Vector3DStack::operator / (float s) const
{
if (fabs(s) < 1e-10) {
... throw some exception to indicate you are dividing a vector by zero.
}
return Vector3DStack(x / s, y / s, z / s);
}
0

Другие решения

Бросить std::invalid_argument, который вытекает из std::logic_error; это указывает, что что-то не так с логическим потоком программы через недопустимый аргумент.

2

Это действительно зависит от того, для чего будет использоваться Vector3DStack.

Вы могли бы

  • бросить исключение
  • сделать его настраиваемым (возможно, проверка происходит только в режиме отладки)
  • просто позвольте div на ноль вернуть Nan — вызывающая сторона может проверить с помощью std :: isnan ()
  • уточнить проблему. Запишите, что ответственность вызывающего абонента состоит в том, что он не установил s в 0 (это называется предварительным условием)

Что лучше, зависит.

2

С вами должен вернуть значение от оператора, у вас есть два варианта:

  1. Бросить исключение (определенно предпочтительнее)
  2. Вернуть вектор, состоящий из трех NaNs.

Кстати, вы не следует chceck, является ли значение с плавающей запятой равно к нулю, потому что вы получите много ложных негативов. Из-за специфической арифметики с плавающей точкой, вам лучше сравнить делитель с очень маленьким значением (которое меньше, чем все, что вы используете в своих алгоритмах, например, если вы работаете с 1e-9 значения, выберите 1e-20).

0

Соответствующее поведение зависит от спецификации функции. Функция может быть написана без какой-либо проверки (это прекрасно работает с IEEE-совместимой математикой с плавающей точкой); он может проверить на 0 и выдать исключение; он может проверить на 0 и отменить; он может проверить на 0 и просто вернуться. Все эти варианты поведения разумны, и невозможно сказать, что является лучшим выбором без контекста. Это все равно, что спросить: «Я собираюсь отправиться в путешествие. Должен ли я ездить или летать?».

0
По вопросам рекламы [email protected]