Reputation: 643
I'm trying to write a simple method in Java that return the reverse of a number (in the mathematical way, not string-wise). I want to take care of boundary conditions since a number whose reverse is out of int range would give me a wrong answer. Even to throw exceptions, I'm not getting clearcut logic. I've tries this code.
private static int reverseNumber(int number) {
int remainder = 0, sum = 0; // One could use comma separated declaration for primitives and
// immutable objects, but not for Classes or mutable objects because
// then, they will allrefer to the same element.
boolean isNegative = number < 0 ? true : false;
if (isNegative)
number = Math.abs(number); // doesn't work for Int.MIN_VALUE
// http://stackoverflow.com/questions/5444611/math-abs-returns-wrong-value-for-integer-min-value
System.out.println(number);
while (number > 0) {
remainder = number % 10;
sum = sum * 10 + remainder;
/* Never works, because int won't throw error for outside int limit, it just wraps around */
if (sum > Integer.MAX_VALUE || sum < Integer.MIN_VALUE) {
throw new RuntimeException("Over or under the limit");
}
/* end */
/* This doesn't work always either.
* For eg. let's take a hypothetical 5 bit machine.
* If we want to reverse 19, 91 will be the sum and it is (in a 5 bit machine), 27, valid again!
*/
if (sum < 0) {
throw new RuntimeException("Over or under the limit");
}
number /= 10;
}
return isNegative ? -sum : sum;
}
Upvotes: 0
Views: 774
Reputation: 20899
Your approach of dividing by 10, transfering the reminder to the current result * 10 is the way to go.
The only thing you are doing wrong is the check for the "boundary violation", because
sum > Integer.MAX_VALUE || sum < Integer.MIN_VALUE
can ofc. NEVER be true - Otherwhise MIN and MAX wouldn't have any meaning.
So, think mathematical :-)
sum = sum * 10 + remainder;
should not exceed Integer.MAX_VALUE
, i.e.
(!)
Integer.MAX_VALUE >= sum * 10 + remainder;
or transformed:
(!)
(Integer.MAX_VALUE - remainder) / 10 >= sum
So, you can use the following check BEFORE multiplying by 10 and adding the remainder:
while (number > 0) {
remainder = number % 10;
if (!(sum <= ((Integer.MAX_VALUE -remainder) / 10))) {
//next *10 + remainder will exceed the boundaries of Integer.
throw new RuntimeException("Over or under the limit");
}
sum = sum * 10 + remainder;
number /= 10;
}
simplified (DeMorgan) the condition would be
if (sum > ((Integer.MAX_VALUE -remainder) / 10))
which makes perfect sence - because its exactly the reversed calculation of what your next step will be - and if sum is already GREATER than this calculation - you will exceed Integer.MAX_VALUE
with the next step.
Untested, but that should pretty much solve it.
Upvotes: 2