数据类型范围及范围溢出解决方案

原因

我注意到LeetCode中有一道中等难度的题——《整数反转》通过率很低,但是我看完题目觉得挺简单的,想着提高一下它的通过率,然后就随手写了段代码,测试都通过了,提交时却报错。

代码:

class Solution {
    public int reverse(int x) {
        int  result = 0;
        boolean flag = true;

        if (x < 0) {
            x = -x;
            flag = !flag;
        }


        while(x > 0){
            int currentDigit = x % 10;
            result = result * 10 + currentDigit;
            x = x / 10;
        }
        
        result = flag ? result : -result;
        
        if (result >= Integer.MIN_VALUE && result <= Integer.MAX_VALUE) {
            return result;
        } else {
            return 0;
        }
    }
}

提交的时候报错:

我一看结果就知道我没有考虑到整数类型的溢出问题,难怪这道题的通过率这么低。

int类型的范围

Java中int类型的值的范围是从 -2^31 到 2^31 - 1,具体数值是:

  • 最小值:-2,147,483,648
  • 最大值:2,147,483,647

这个范围是由int类型占用的内存大小决定的。在Java中,int类型占用4个字节(即32位),其中最高位表示符号位(0代表正数,1代表负数),剩余31位用于存储数值部分。由于这种二进制表示方式,所以它可以表示的最大正整数是2的31次方减1,而最小负整数则是-2的31次方。

Java中基本数据类型的范围

为了以防下次我再忽视这种问题,我将java中基本数据类型的范围都罗列了一遍。

Java中的基本数据类型包括整数型、浮点型、字符型和布尔型,其范围如下:

  1. 整数型

    • byte: 占用1个字节(8位),有符号整数,范围从 -128 到 127
    • short: 占用2个字节(16位),有符号整数,范围从 -32,768 到 32,767
    • int: 占用4个字节(32位),有符号整数,范围从 -2,147,483,648 到 2,147,483,647
    • long: 占用8个字节(64位),有符号整数,范围从 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
  2. 浮点型

    • float: 占用4个字节(32位),单精度浮点数,根据IEEE 754标准,能表示非常大的正负数值以及很小的近似值,但不精确。
    • double: 占用8个字节(64位),双精度浮点数,同样遵循IEEE 754标准,具有更大的精度和更大的数值范围。
  3. 字符型

    • char: 占用2个字节(16位),无符号整数,用来表示Unicode字符,范围从 U+0000 到 U+FFFF(即 0 到 65535)。
  4. 布尔型

    • boolean: 表示逻辑值,不直接对应特定的内存大小。在Java中,只包含两个可能的值:true 和 false

范围溢出方法的解决方案

我通过搜寻资料总结了一些范围溢出的解决方案

  1. 选择合适的数据类型

    如果在处理整数时出现溢出,可以考虑使用更大范围的整数类型。例如在Java中,如果int类型不足以容纳计算结果,可以尝试改用longBigInteger(无符号大整数类)。
  2. 检查并限制输入值

    在程序接收输入或者进行操作前,先检查数值是否在允许范围内,避免直接进行可能导致溢出的操作。
  3. 模块化运算

    对于某些特定场景,如计数、循环等,可以采用模运算来确保数值始终在某个范围内。
  4. 使用库函数或语言特性

    许多编程语言提供了检测溢出的功能,例如Java中的Math.addExact()Math.multiplyExact()等方法可以在执行操作时检查是否发生溢出,并在发生溢出时抛出异常。
  5. 位运算

    对于一些特殊的计算需求,比如二进制位操作,可以通过理解并利用位运算的特点来进行安全的计算,避免溢出。
  6. 使用浮点数代替整数

    在一定精度要求下,对于非常大的数值,可以考虑使用浮点数类型,但需要注意的是浮点数并不能精确表示所有整数,且有其自身的精度限制和误差问题。
  7. 分治算法

    对于大型计算任务,可以采用分治策略将大问题分解为小问题分别处理,每一步都确保不发生溢出。
  8. 使用无符号类型

    部分编程语言支持无符号整数类型,它们可以提供更大的正数范围,但在处理负数时需要额外注意。

整数反转的代码修正

class Solution {
    public int reverse(int x) {
        Long  result = 0L;           //将result改成Long类型,则不会出现int类型的溢出问题
        boolean flag = true;

        if (x < 0) {
            x = -x;
            flag = !flag;
        }


        while(x > 0){
            int currentDigit = x % 10;
            result = result * 10 + currentDigit;
            x = x / 10;
        }
        
        result = flag ? result : -result;
        
        if (result >= Integer.MIN_VALUE && result <= Integer.MAX_VALUE) {
            return result.intValue(); //因为函数是int类型的,所以需要将Long类型先转成int类型
        } else {
            return 0;
        }
    }
}

只需要将代码中的result改成Long类型,因此在while循环的过程中就不会出现int类型溢出的问题,最后再返回的过程中再将result类型转换成int类型。

  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值