• Java中的基本数据类型int及数据溢出


    1. 概述

    Java语言内置了八种基本数据类型:六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。

    其中int 数据类型是++32位++、++有符号++的以++二进制补码++表示的整数

    • 最小值是 -2,147,483,648(-2^31);
    • 最大值是 2,147,483,647(2^31 - 1);
    • 一般的整型变量默认为 int 类型;
    • int的默认值是 0
    public class Test {  
        public static void main(String[] args) {
            System.out.println("二进制长度:" + Integer.SIZE); 
            System.out.println("最小值Integer.MIN_VALUE = " + Integer.MIN_VALUE); 
            System.out.println("最大值Integer.MAX_VALUE = " + Integer.MAX_VALUE);  
        }
    }
    

    输出结果:

    二进制长度:32
    最小值Integer.MIN_VALUE = -2147483648
    最大值Integer.MAX_VALUE = 2147483647
    

    2. 补码

    Java里的int是有符号的,二进制系统是通过补码来保存数据的,最高位为1的数字用来表示负数,而最高位为0的数字表示非负数。

    正数补码等于原码,负数的补码等于其绝对值的反码+1。例如:-1的补码就是绝对值1的反码(按位取反) 再+1。计算方式如下:

      0000 0000 0000 0000 0000 0000 0000 0001      => 1的二进制
      1111 1111 1111 1111 1111 1111 1111 1110      => 1的反码
    + 0000 0000 0000 0000 0000 0000 0000 0001
    -----------------------------------------
      1111 1111 1111 1111 1111 1111 1111 1111      => -1的补码
    

    常见整数对应的补码:

    1000 0000 0000 0000 0000 0000 0000 0000 => -2147483648
    1111 1111 1111 1111 1111 1111 1111 1111 => -1
    0000 0000 0000 0000 0000 0000 0000 0000 => 0
    0000 0000 0000 0000 0000 0000 0000 0001 => 1
    0111 1111 1111 1111 1111 1111 1111 1111 => 2147483647
    

    例:获取整数二进制

    public class Test {
        public static void main(String[] args) {
            int[] arrayInt = new int[] {Integer.MAX_VALUE, 0, 1, -1, Integer.MIN_VALUE};
            for (int x : arrayInt) {
                String binaryString = Integer.toBinaryString(x);
                int length = Integer.SIZE;
                while(binaryString.length() < length){
                    // 在不足的位数前加“0”
                    binaryString = "0" + binaryString;
                }
                // 为了方便查看,每4位插入分割符
                int m = binaryString.length()/4 - 1;
                StringBuffer stringBuffer = new StringBuffer(binaryString);
                for (int i = m; i > 0; i--) {
                    int j = 4 * i;
                    stringBuffer.insert(j,' ');
                }
                System.out.printf("%,14d", x);
                System.out.print(" 对应的二进制为:");
                System.out.printf("%s%n", stringBuffer.toString());
    
            }
        }
    }
    

    输出结果:

     2,147,483,647 对应的二进制为:0111 1111 1111 1111 1111 1111 1111 1111
                 0 对应的二进制为:0000 0000 0000 0000 0000 0000 0000 0000
                 1 对应的二进制为:0000 0000 0000 0000 0000 0000 0000 0001
                -1 对应的二进制为:1111 1111 1111 1111 1111 1111 1111 1111
    -2,147,483,648 对应的二进制为:1000 0000 0000 0000 0000 0000 0000 0000
    

    3. 数据溢出

    首先,基本的数据类型(long,int,short,byte,char,float,double)都有自己能够保存的数据范围。

    数据溢出

    当某一种类型的数值已经达到了此类型能够保存的最大值之后,再继续扩大,或者达到了最小值后再继续缩小,就会出现数据溢出问题。而溢出不会出错,却会得到一个意外的结果:

    public class MyDemo{
    	public static void main(String args []){
    		int a = Integer.MAX_VALUE;//定义一个int型变量a的值为int型能够保存的最高值
    		System.out.println(a + 1);
    		int b = Integer.MIN_VALUE;//定义一个int型变量a的值为int型能够保存的最小值
    		System.out.println(b - 1);
    	}
    }
    

    输出结果:

    -2147483648
    2147483647
    

    下面解释出现这种情况的原因:

      0111 1111 1111 1111 1111 1111 1111 1111      => 2147483647的补码
    + 0000 0000 0000 0000 0000 0000 0000 0001
    -----------------------------------------
      1000 0000 0000 0000 0000 0000 0000 0000      => -2147483648的补码
    
    • 最轻微的上溢是 INT_MAX + 1 :结果是 INT_MIN。
    • 最严重的上溢是 INT_MAX + INT_MAX :结果是 -2。
    • 最轻微的下溢是 INT_MIN - 1 :结果是 INT_MAX。
    • 最严重的下溢是 INT_MIN + INT_MIN :结果是 0。

    最大值加1时,反而变成范围的最小值,加2变成范围的次小值,这种情况可以想象出一个循环。

    数据溢出的解决办法:

    我们已经知道,在整型中,能够保存的数值范围最大的是long型;在浮点型中,能够保存的数值范围最大的是double型。所以在遇到数据溢出问题时,我们可以先把能够保存的数值范围小的类型转换为范围大的类型,再进行运算。

    例:

    public class Test{
    	public static void main(String args []){
    	    //定义一个int型的最大值
    		int x = Integer.MAX_VALUE;
    		System.out.println((long)x+2);
    	}
    }
    

    输出结果是:2147483649

    ---- 作者:快乐随行 著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明原文作者及出处。 ----
  • 相关阅读:
    80%的程序员都不了解的调试技巧
    80%的程序员都不了解的调试技巧
    [SQL]死锁处理语句
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    2020年1月数据库流行度排行:从万里挑二到波澜不惊
    对项目中数据访问流程的理解
    set_global_opts使用说明
    对JNDI数据源的理解
  • 原文地址:https://www.cnblogs.com/jddreams/p/14361152.html
Copyright © 2020-2023  润新知