考虑边界条件的数的逆



我正试图用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;

}

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

你唯一做错的是检查"边界违规",因为

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

罐头ofc。永远不要是真的——否则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;
}

简化后(德摩根)条件为

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

这是一个完美的感觉,因为这正是对下一步的反向计算,如果总和已经大于这个计算,那么下一步你将超过Integer.MAX_VALUE

未测试,但这应该可以解决问题。

相关内容

  • 没有找到相关文章

最新更新