反转一个处理边界条件的数字

时间:2014-10-06 18:00:43

标签: java integer-overflow boundary

我试图在Java中编写一个简单的方法来返回数字的反转(以数学方式,而不是字符串方式)。我想要处理边界条件,因为反转超出int范围的数字会给我一个错误的答案。即使抛出异常,我也没有得到明确的逻辑。我试过这段代码。

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;

}

1 个答案:

答案 0 :(得分:2)

你的方法除以10,将提醒转移到当前结果* 10是要走的路。

你唯一错误的是检查“边界违规”,因为

sum > Integer.MAX_VALUE || sum < Integer.MIN_VALUE

可以。绝对没有 - Otherwhise MIN和MAX没有任何意义。

所以,想想数学 :-)

sum = sum * 10 + remainder;

不应超过Integer.MAX_VALUE,即

                 (!)
Integer.MAX_VALUE >= sum * 10 + remainder;

或转化:

                                    (!)
(Integer.MAX_VALUE - remainder) / 10 >= sum

因此,您可以在乘以10并添加余数之前使用以下检查:

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;
}

简化(DeMorgan)条件

if (sum > ((Integer.MAX_VALUE -remainder) / 10))

这样可以完美呈现 - 因为它完全反过来计算你的下一步将是什么 - 如果总和已经超过这个计算 - 你将在下一步超过Integer.MAX_VALUE

未经测试,但这应该可以解决它。