2013-11-07 4 views
0

Нам было предложено создать класс 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

у вас есть это, выбросить исключение – john

+2

Зачем вообще это мешать? – Bart

ответ

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); 
} 
2

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

+0

Хм, если вы пишете библиотеку, например, я считаю, что invalid_argument более уместен. Конечно, это сильно зависит от конкретного случая. –

+0

@IvayloStrandjev Отредактировано –

0

Поскольку вы должны возвращать значение от оператора, у вас есть два варианта:

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

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

0

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

2

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

Вы можете

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

От кого лучше всего зависит.

+0

Еще одно решение: укажите тип возврата 'boost :: optional ' и верните 'boost :: none', если ввод неправильный (не рекомендуется для этого конкретного случая). –

 Смежные вопросы

  • Нет связанных вопросов^_^