我正试图用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
。
未测试,但这应该可以解决问题。