java中Int范围越界检测

LeetCode上老有String 或者 char[]转int的算法,在计算之前需要分析计算是否会超过int 的范围。

解决溢出问题有两个思路,第一个思路是通过字符串转换加try catch的方式来解决,第二个思路就是通过数学计算来解决。
由于字符串转换的效率较低且使用较多库函数,所以解题方案不考虑该方法,而是通过数学计算来解决。
通过循环将数字x的每一位拆开,在计算新值时每一步都判断是否溢出。
溢出条件有两个,一个是大于整数最大值MAX_VALUE,另一个是小于整数最小值MIN_VALUE,设当前计算结果为ans,下一位为pop。
从ans * 10 + pop > MAX_VALUE这个溢出条件来看
当出现 ans > MAX_VALUE / 10 且 还有pop需要添加 时,则一定溢出
当出现 ans == MAX_VALUE / 10 且 pop > 7 时,则一定溢出,7是2^31 - 1的个位数
从ans * 10 + pop < MIN_VALUE这个溢出条件来看
当出现 ans < MIN_VALUE / 10 且 还有pop需要添加 时,则一定溢出
当出现 ans == MIN_VALUE / 10 且 pop < -8 时,则一定溢出,8是-2^31的个位数

该算法用于高位乘10 并加低位操作之前。

算法如下:

/**
 * int 是否越界检验算法
 *
 * @param number        需要校验的数字
 * @param valueOfCharAt 需要校验的最低位
 * @param flag          正负标志
 * @return
 */

private int verification(int number, int valueOfCharAt, int flag) {
    long shangjie = (long) Math.pow(2, 31) - 1;     // 上限
    long xiajie = -(long) Math.pow(2, 31);          // 下限
    int result = 0;
    if (flag == -1) {                               // 负数校验
        if (((-number) < xiajie / 10) || (-number == (xiajie / 10) && valueOfCharAt > 8)) {
            result = 1;
        }
    } else {                                        // 正数校验
        if ((number > shangjie / 10) || ((number == shangjie / 10) && valueOfCharAt > 7)) {
            result = 1;
        }
    }
    return result;
}

作者:guanpengchn
链接:https://leetcode-cn.com/problems/reverse-integer/solution/hua-jie-suan-fa-7-zheng-shu-fan-zhuan-by-guanpengc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

同时转自:赵小白666

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/qq_20662113/article/details/98734092

<think>嗯,用户问Java数组索引越界会不会引发编译错误。这个问题看起来基础,但需要仔细分析。首先,我得回忆一下Java的编译和运行机制。编译错误通常是指语法错误,比如缺少分号或者拼写错误,而运行时错误则是程序运行过程中出现的,比如空指针或者数组越界。 那数组索引越界属于哪一种呢?比如,假设代码中有一个数组arr,长度是3,用户写了arr[5],这时候在编译的时候,编译器能发现吗?可能不会,因为数组的长度在运行时才能确定,除非是声明时明确指定了长度,但即使如此,如果索引是字面量,比如arr[5],而数组长度明显不够,编译器会不会报错? 比如,声明int[] arr = new int[3];然后访问arr[5],这个时候,编译的时候会不会报错?根据我的记忆,Java编译器不会检查数组索引的范围,因为索引可能是变量,只有在运行时才能确定。所以这种情况下,编译能通过,但运行时会抛出ArrayIndexOutOfBoundsException异常。 不过,有没有特殊情况?比如,如果使用常量表达式作为索引,例如,final int index = 5;然后声明数组长度是3,这时候访问arr[index],这时候编译器是否检测到?可能还是不会,因为final变量虽然不可变,但数组的长度可能在运行时才确定,所以编译器可能不会在编译时检查这个情况。 所以,结论应该是数组索引越界不会导致编译错误,而是运行时异常。用户可能混淆了编译错误和运行时异常的区别,需要明确说明这一点。同时,用户可能在实际编码时遇到这个问题,需要指导如何避免,比如检查数组长度,使用循环时注意边界条件,或者使用增强for循环等。 另外,用户可能想知道如何检测这类问题,可以建议在代码中加入范围检查,或者使用异常处理机制。但重点还是区分编译期和运行时的错误类型。需要举例子说明编译错误和运行时错误的不同,比如语法错误导致编译失败,而数组越界在运行时报异常。 总结回答的结构应该是先明确回答“不会引发编译错误”,然后解释原因,区分编译错误和运行时异常,最后给出示例和避免方法。确保用户理解两者的区别,以及如何在实际编码中处理数组越界的问题。</think>Java数组索引越界**不会引发编译错误**,但会在**运行时**抛出`ArrayIndexOutOfBoundsException`异常。以下是逐步分析: --- ### 1. **编译错误 vs 运行时异常** - **编译错误**:由语法或类型不匹配等问题引起,导致代码无法生成.class文件。 - 例如:缺少分号、未声明变量等。 - **运行时异常**:代码语法正确,但执行时逻辑出现问题。 - **数组索引越界**属于这一类。 --- ### 2. **为什么不会触发编译错误?** - Java编译器**不检查数组索引范围**,因为索引值可能是动态计算的,无法在编译时确定。 - 示例代码: ```java int[] arr = {1, 2, 3}; int value = arr[5]; // 编译通过,但运行时报错 ``` - 编译阶段无法预知`arr[5]`是否越界,因此不会报错。 --- ### 3. **运行时异常的触发条件** 当访问数组时,若索引值满足以下任一条件: 1. **索引 < 0** 2. **索引 ≥ 数组长度** 会立即抛出`ArrayIndexOutOfBoundsException`。 --- ### 4. **如何避免数组越界?** - **检查索引范围**:访问数组前验证索引值。 ```java if (index >= 0 && index < arr.length) { int value = arr[index]; } ``` - **使用增强for循环**(适用于遍历): ```java for (int num : arr) { System.out.println(num); } ``` --- ### 5. **示例对比** #### 编译错误(语法问题): ```java int[] arr = new int[3] // 编译错误:缺少分号 ``` #### 运行时异常(逻辑问题): ```java int[] arr = {1, 2, 3}; System.out.println(arr[3]); // 运行时抛出ArrayIndexOutOfBoundsException ``` --- ### 总结 - **编译阶段**:Java只检查语法和类型,不验证索引范围。 - **运行阶段**:JVM会严格检查索引有效性,越界则立即终止程序并报错。 - **建议**:通过预检查索引或使用安全的遍历方式避免此类问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值