Anoop Dixith
Anoop Dixith

Reputation: 643

Reverse of a number taking care of boundary conditions

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

Answers (1)

dognose
dognose

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

Related Questions