Originally Posted by
Elysia
The problem is that if there is an actual overflow or underflow for the type because it cannot represent the actual value, then it's impossible to check the result.
The trick is to do things to check if an operation would overflow/underflow BEFORE doing the operation. Mathematics is great for finding those things to do.
Originally Posted by
Elysia
My apologies. My thinking was in error. Of course you're right.
But you've given me light. I don't think I'm used in thinking in terms of equations for computer mathematics problems...
Mathematics is all about describing a problem in a way that allows it to be solved, and finding alternative but equivalent operations if one method does not work for some reason. That philosophy is quite useful with programming.
Let's say, for sake of discussion, we want to throw an exception if multiplying two positive valued ints causes an overflow (again for sake of discussion, this means "produces a result greater than INT_MAX").
With handling of overflows or underflows, one technique is to do the operation (multiplication, division, etc), check if an overflow/underflow has occurred, and (if it has) decide what to do next (recovery action, etc). The practical problem is that techniques by which overflow/underflow are reported are machine dependent, so the methods of detecting them are too.
To meet our requirement, we could do this;
Code:
/* assume a and b are both > 0 and <= INT_MAX */
result = a*b;
if (overflow_detected(result))
throw OurException;
The problem with this is that the techniques of detecting an overflow are machine dependent (particularly as some machines wrap values, so the test is not simply "if (result > INT_MAX)". The techniques for recovery of such a condition are also machine dependent (more so for floating point, but still true for ints, as there is implementation defined behaviour).
Another way is to detect the potential overflow BEFORE doing the operation and, if a positive detection occurs, throw the exception and DO NOT do the computation. Since we are trying to detect a situation where a*b > INT_MAX, we can divide by one of the values. So the technique might be
Code:
/* assume a and b are both > 0 and <= INT_MAX */
if (INT_MAX/a < b) /* overflow would occur if we did multiplication */
throw OurException;
result = a*b;
This has the same net effect, but no overflow occurs that needs to be recovered from in a machine dependent manner.