如果判断整数是否越界

经常会遇到类似于“把字符串转成32位的整数(-2^31-1 ~ ? ” 2^31),如果超出这个范围就返回0,假设不存在64位的long整数“。按照题目要求是只能使用int型数来进行处理。所以我们只能在循环里提前一步进行判断,如果下一个操作会溢出,那么则直接返回0.
下面介绍两种方式。
方式一:

int len = str.length();
        // str.charAt(i) 方法回去检查下标的合法性,一般先转换成字符数组
        char[] charArray = str.toCharArray();

        // 1、去除前导空格
        int index = 0;
        while (index < len && charArray[index] == ' ') {
            index++;
        }

        // 2、如果已经遍历完成(针对极端用例 "      ")
        if (index == len) {
            return 0;
        }

        // 3、如果出现符号字符,仅第 1 个有效,并记录正负
        int sign = 1;
        char firstChar = charArray[index];
        if (firstChar == '+') {
            index++;
        } else if (firstChar == '-') {
            index++;
            sign = -1;
        }

        // 4、将后续出现的数字字符进行转换
        // 不能使用 long 类型,这是题目说的
        int res = 0;
        while (index < len) {
            char currChar = charArray[index];
            // 4.1 先判断不合法的情况
            if (currChar > '9' || currChar < '0') {
                break;
            }

            // 题目中说:环境只能存储 32 位大小的有符号整数,因此,需要提前判:断乘以 10 以后是否越界
            if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && (currChar - '0') > Integer.MAX_VALUE % 10)) {
                return Integer.MAX_VALUE;
            }
            if (res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10 && (currChar - '0') > -(Integer.MIN_VALUE % 10))) {
                return Integer.MIN_VALUE;
            }

            // 4.2 合法的情况下,才考虑转换,每一步都把符号位乘进去
            res = res * 10 + sign * (currChar - '0');
            index++;
        }
        return res;
    }

如上所示,使用 ”if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && (currChar - ‘0’) > Integer.MAX_VALUE % 10))“。如果条件成立则表示溢出。

第二种方式就简单一点:

public int myAtoi(String s) {
        int sign = 1, ans = 0, index = 0;
        char[] array = s.toCharArray();
        if (index < array.length && (array[index] == '-' || array[index] == '+')) {
            sign = array[index++] == '-' ? -1 : 1;
        }
        while (index < array.length && array[index] <= '9' && array[index] >= '0') {
            int digit = array[index++] - '0';
            if (ans > (Integer.MAX_VALUE - digit) / 10) {
                return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
            }
            ans = ans * 10 + digit;
        }
        return ans * sign;
    }

如上所示,直接使用 if (ans > (Integer.MAX_VALUE - digit) / 10) 进行判断,如果大于则表示溢出。

### C语言中整数溢出的判断方法 在C语言中,整数类型的取值范围有限,因此在执行算术运算时可能会发生溢出。以下是几种常见的整数溢出判断方法: #### 方法一:基于结果与操作数的关系 对于两个非负整型变量 `a` 和 `b` 的加法运算,可以通过比较它们之间的关系来检测是否存在溢出。具体实现如下: ```c #include <stdio.h> #include <limits.h> int check_overflow_addition(int a, int b) { if (b > 0 && a > INT_MAX - b) { // 如果 b 是正数且 a 超过了允许的最大值 printf("Overflow occurred.\n"); return 1; } if (b < 0 && a < INT_MIN - b) { // 如果 b 是负数且 a 小于允许的最小值 printf("Underflow occurred.\n"); return 1; } return 0; } ``` 这种方法通过验证 `(INT_MAX - b)` 是否小于 `a` 来判断是否有上溢情况[^2]。 --- #### 方法二:利用寄存器标志位 某些硬件架构提供了专门用于检测溢出的状态标志位。例如,在 x86 架构中,可以使用汇编指令访问这些状态标志位。然而,这种方式依赖具体的处理器特性,并不具有跨平台兼容性。一种简单的模拟方式如下所示: ```c void detect_overflow_with_sign_bit(unsigned int a, unsigned int b) { if ((a + b) < a) { // 若结果小于任意一个操作数,则发生了溢出 printf("Unsigned overflow detected.\n"); } else { printf("No overflow.\n"); } } ``` 此逻辑适用于无符号整数类型的操作[^3]。 --- #### 方法三:借助更大数据类型的存储空间 为了防止潜在的数据丢失问题,可以在临时计算过程中升级到更大的数据类型来进行处理后再降级回原目标类型。比如从 `int` 提升至 `long long` 类型完成相应运算之后再转换回去即可。 ```c #include <stdio.h> #include <stdint.h> bool is_safe_to_cast(long long value) { return (value >= INT_MIN && value <= INT_MAX); } // 使用更大容量的数据类型进行安全检查 int safe_addition(int a, int b) { long long result = (long long)a + (long long)b; if (!is_safe_to_cast(result)) { fprintf(stderr, "Integer Overflow Detected!\n"); exit(EXIT_FAILURE); // 或者抛出自定义异常机制 } return (int)result; // 安全地强制转型回来 } ``` 上述代码片段展示了如何通过扩展数值表达域的方式规避可能存在的风险[^4]。 --- ### 总结 以上介绍了三种不同的策略用来应对C程序设计中的整数越界隐患。实际应用当中可以根据具体情况选用最合适的方案加以防范措施实施到位从而保障系统的健壮性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值