Reputation: 73
#include <stdio.h>
int reverse(int);
int reverse(int x) {
int negative = 0;
if (x < 0)
negative = x;
if (negative != 0) {
x = 0 - x;
}
int y = 0, temp;
while (x > 0) {
temp = x % 10;
x = x / 10;
y = (y * 10) + temp;
}
if (negative == 0) {
return y;
} else {
return 0 - y;
}
}
int main() {
int x, y;
printf("Enter your number: \n");
scanf("%d", &x);
y = reverse(x);
printf("The reversed number is: %d\n", y);
return 0;
}
This program reverses a signed integer. I was unable to check if the revered integer y, is out of bounds. I'm not able to attain clarity on the topic of overflow. If I ask the compiler using scanf to scan an integer and enter an integer that is out of range of the integer, what will happen? Does the value change as it is stored?
Upvotes: 0
Views: 370
Reputation: 149145
In standard C, overflow is an exceptional condition and behaviour is then undefined per standard. From draft n1570 for C11, 6.5 Expressions § 5:
If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.
That means that you cannot process overflow in a way that would be defined per standard. That being said, most compilers simply keep the low order bits of the result that can fit in the type representation and ignore the highest order bit(s). This is what MSVC, gcc, and clang do.
From now on, I will assume that your system uses the int32_t
(resp. int16_t
or int64_t
) for signed int and ignores overflow. It is not mandated per standard but is common enough and is probably what your system does.
There are 2 possible overflows in your code. First is the scanf
function: as said by @n.m., nothing is said for the behaviour of this family of function if the input sequence does not fit in the type. I will assume that the submitted number is acceptable as a signed int (between INT_MIN and INT_MAX). Anyway, it is trivial to have it detected by the user: just display x
: if it is not the just typed number, then an overflow occured.
Second is here:
y = (y * 10) + temp;
Here again it is easy to test for overflow, by doing the reverse operations and controling that all was fine:
int next = (y * 10) + temp;
if ((next < 0) || (y != (next - temp) / 10)) {
// an overflow occured...
...
In theory, nothing can guarantee that negating a positive int is a valid negative int, but this is true for the intXX_t
types, so that should be enough to detect an overflow in the reverse
function.
Upvotes: 0
Reputation: 120069
You seem to have two different questions regarding overflow.
The answers are as follows.
y <= INT_MAX / 10
, you can be sure y * 10
will not overflow. Same thing about ... + temp
.scanf
and friends do not have any way to protect you from overflow, other than limiting field width and thus input range (but you cannot limit the range exactly to INT_MAX
if you are reading a decimal). If the scanned value doesn't fit into the destination type, the behaviour is undefined. The only way to safely convert a string with the exact range is with strtol
and friends. These functions detect overflow and set errno
accordingly.Upvotes: 1