xqqlyx

7.反转数字-处理溢出的条件-Java

题目:反转数字

描述
给定一个32位的有符号整数num,将num中的数字部分反转,最后返回反转的结果。
1.只反转数字部分,符号位部分不反转。
2.反转后整数num超过 32 位的有符号整数的范围$[-2^{31} ,2^{31}-1] $ ,返回 0。
3.假设本题不允许存储 64 位整数(有符号或无符号,即C++不能使用long long ,Java不能使用long等)。
数据范围:
$ -2^{31} <= x <= 2^{31}-1 $

错误处理溢出代码

 if(x>=(2<<32-1)) return 0;
 if(x<=-(2<<32)) return 0;//int类型根本无法表示。。。神

正确处理溢出代码

if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && digit > 7)) {
            return 0;
        }
if (res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10 && digit < -8)) {
            return 0;
        }

原理

在执行可能导致溢出的操作前,用反向运算判断是否会溢出,避免直接计算溢出值。以 res = res * k + digit 为例(k 是倍数,如 10、3 等),步骤如下:
确定目标范围:比如 int 的范围是 [min, max](min = -2147483648,max = 2147483647)。
拆分操作:要执行 res * k + digit,先判断 res * k 是否会溢出,再判断加 digit 后是否溢出。
反向判断:
若 k > 0:

  • 正数溢出:res > max / k → 此时 res * k 必超 max;
    若 res == max / k,则需额外判断 digit > max % k(超出余数则溢出)。
  • 负数溢出:res < min / k → 此时 res * k 必小于 min;
    若 res == min / k,则需额外判断 digit < min % k(超出余数则溢出)。

  Math.abs(Integer.MIN_VALUE);

输出仍为Integer.MIN_VALUE。

完整代码

public int reverse(int x) {
    int res = 0;
    while (x != 0) {
        int digit = x % 10;
        x = x / 10;
        if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && digit > 7)) {
            return 0;
        }
        if (res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10 && digit < -8)) {
            return 0;
        }
        res = res * 10 + digit;
    }
    return res;
}

错误代码

public int reverse (int x) {
        boolean sign=false;
 	if(x>=(2<<32-1)) return 0;
 	if(x<=-(2<<32)) return 0;//int类型根本无法表示。。。神
        if(x>=0) sign=true;
        if(!sign) x=Math.abs(x);//Math.abs有坑
        int res=0;
        while(x>0){
            res=res*10+x%10;//具有溢出的风险 res每次都扩大10倍并且加上一个0-9的数
            x=x/10;
        }
        return sign?res:-res;//有关符号判断根本不用判断,修改while条件为!=10。
	//用除法和取余的反向运算,在实际计算前拦截溢出,这是处理整数溢出的标准解法。
    }

posted on 2025-09-28 12:28  烫烫烫烫热  阅读(12)  评论(0)    收藏  举报