Страницы

Поиск по вопросам

суббота, 4 января 2020 г.

Работа с ошибками в С++. Деление на ноль

#cpp


Пишу свой проект в учебных целях для работы с обыкновенными дробями.

#include 
#include "simple_math.h"

using namespace std;
using namespace simple_math;

int main()
{
    cout << fraction(1, 2) + fraction(1, 3); // в результате выводит "5 / 6"
    return 0;
}


Что если знаменатель какой-то дроби будет равен нулю. Понятно, что нужно выкинуть
ошибку, но как это сделать? 

if(b == 0)
{
    // ОШИБКА!
}

    


Ответы

Ответ 1



Если вы хотите работать по C++'ному, то нужно генерировать исключение. Можно собственного типа, можно наследовать от стандартного exception - это уже вопрос стиля и предпочтений. Примерно так - class DivideByZero {}; ... if (b == 0) throw DivideByZero(); ... try { cout << fraction(1, 2) + fraction(1, 3); // в результате выводит "5 / 6" } catch(DivideByZero&) { cerr << "Divide by zero error!\n" } Или, если воспользоваться стандартным - думаю, тут правильнее invalid_argument - то if (b == 0) throw invalid_argument("Divide by zero error in fraction!"); ... try { cout << fraction(1, 2) + fraction(1, 3); // в результате выводит "5 / 6" } catch(exception&e) { cerr << e.what() << endl; }

Ответ 2



Если вас волнует производительность - учтите, что процессор сам умеет швырять такие исключения при делении на 0, однако, в стандарте C++ такой обработки нет - ее надо сделать: GCC #include #include int main() { std::shared_ptr handler( signal(SIGFPE, [](int signum) {throw std::logic_error("FPE"); }), [](__sighandler_t f) { signal(SIGFPE, f); }); int i = 0; cin >> i; // what if someone enters zero? try { i = 5/i; } catch (std::logic_error e) { std::cerr << e.what(); } } Visual C++ #include #include int main() { std::shared_ptr handler( _set_se_translator([](unsigned u, EXCEPTION_POINTERS* p) { switch(u) { case FLT_DIVIDE_BY_ZERO: throw std::logic_error("Divide by zero"); ... default: throw std::logic_error("SEH exception"); } }), [](_se_translator_function f) { _set_se_translator(f); }); int i = 0; try { i = 5 / i; } catch(std::logic_error e) { std::cerr << e.what(); } } Оригинал на enSO Почему это лучше сравнения с 0 перед делением? это задействует аппаратные возможности платформы по отлову ошибок работает быстрее (не надо делать лишних сравнений) гарантирует, что вы не забудете где-то сделать проверку

Комментариев нет:

Отправить комментарий