The following code does not catch an exception, when I try to divide by 0. Do I need to throw an exception, or does the computer automatically throw one at runtime?
int i = 0; cin >> i; // what if someone enters zero? try { i = 5/i; } catch (std::logic_error e) { cerr << e.what(); }
Hence, if any number is divided by zero, we get the arithmetic exception .
Definition. Division by zero is a logic software bug that in most cases causes a run-time error when a number is divided by zero.
Values like INFINITY and NaN are available for floating-point numbers but not for integers. As a result, dividing an integer by zero will result in an exception. However, for a float or double, Java allows the operation. The complete code is available over on GitHub.
Java will not throw an exception if you divide by float zero. It will detect a run-time error only if you divide by integer zero not double zero. If you divide by 0.0, the result will be INFINITY.
You need to check it yourself and throw an exception. Integer divide by zero is not an exception in standard C++.
Neither is floating point divide by zero but at least that has specific means for dealing with it.
The exceptions listed in the ISO standard are:
namespace std { class logic_error; class domain_error; class invalid_argument; class length_error; class out_of_range; class runtime_error; class range_error; class overflow_error; class underflow_error; }
and you could argue quite cogently that either overflow_error
(the infinity generated by IEEE754 floating point could be considered overflow) or domain_error
(it is a problem with the input value) would be ideal for indicating a divide by zero.
However, section 5.6
(of C++11
, though I don't think this has changed from the previous iteration) specifically states:
If the second operand of
/
or%
is zero, the behavior is undefined.
So, it could throw those (or any other) exceptions. It could also format your hard disk and laugh derisively :-)
If you wanted to implement such a beast, you could use something like intDivEx
in the following program (using the overflow variant):
#include <iostream> #include <stdexcept> // Integer division/remainder, catching divide by zero. inline int intDivEx (int numerator, int denominator) { if (denominator == 0) throw std::overflow_error("Divide by zero exception"); return numerator / denominator; } inline int intModEx (int numerator, int denominator) { if (denominator == 0) throw std::overflow_error("Divide by zero exception"); return numerator % denominator; } int main (void) { int i = 42; try { i = intDivEx (10, 0); } catch (std::overflow_error &e) { std::cout << e.what() << " -> "; } std::cout << i << std::endl; try { i = intDivEx (10, 2); } catch (std::overflow_error &e) { std::cout << e.what() << " -> "; } std::cout << i << std::endl; return 0; }
This outputs:
Divide by zero exception -> 42 5
and you can see it throws and catches the exception (leaving the return variable untouched) for the divide by zero case.
The %
equivalent is almost exactly the same:
Updated with comments from ExcessPhase
GCC (at least version 4.8) will let you emulate this behaviour:
#include <signal.h> #include <memory> #include <iostream> int main() { std::shared_ptr<void(int)> handler( signal(SIGFPE, [](int signum) {throw std::logic_error("FPE"); }), [](__sighandler_t f) { signal(SIGFPE, f); }); int i = 0; std::cin >> i; // what if someone enters zero? try { i = 5/i; } catch (std::logic_error e) { std::cerr << e.what(); } }
This sets up a new signal handler which throws an exception, and a shared_ptr
to the old signal handler, with a custom 'deletion' function that restores the old handler when it goes out of scope.
You need to compile with at least these options:
g++ -c Foo.cc -o Foo.o -fnon-call-exceptions -std=c++11
Visual C++ will also let you do something similar:
#include <eh.h> #include <memory> int main() { std::shared_ptr<void(unsigned, EXCEPTION_POINTERS*)> handler( _set_se_translator([](unsigned u, EXCEPTION_POINTERS* p) { switch(u) { case FLT_DIVIDE_BY_ZERO: case INT_DIVIDE_BY_ZERO: throw std::logic_error("Divide by zero"); break; ... 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(); } }
And of course you can skip all the C++11-ishness of this and put them in a traditional RAII-managing struct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With